大家都知道,隊列是先進先出的。因此如果我先取出隊列頭部的單個元素,那麼在隊列內部會將數組的每個下表向低位移動一位。如果這個隊列是百萬級別的,那麼可以想象到這個性能是多麼的蛋疼。讓我們換一種思維來解決這個問題:
我將這個數組做成閉環。也就是我取出隊列的頭元素之後,不移動位置,而是留空。再將原先的第二位元素標記位頭元素(下標不動)。如果又有元素進入,則將此元素放入這個數組的空白處。當然如果這個數組還沒有填滿,則先填滿後面的空白,然後再填充通過pop留出的空白元素。
用這種方法,我們就將一個數組做成了一個閉環,不用移動元素的下標也可以做對別的先進先出了,看代碼:
package test;
public class Queue {
public static void main(String[] args) {
Queue st = new Queue(100);
for(int i = 0; i < 98; i++) {
st.push(i);
}
System.out.println("pop first=="+st.pop());
st.push(51);
st.push(52);
st.push(53);
while(st.size() > 0) {
Object dt = st.pop();
if(dt != null) {
System.out.println("data="+dt);
}
}
}
private int size = 0;
private int capacity;
private Object[] data;
private int currHead = 0;
private int MAX_SIZE = Integer.MAX_VALUE;
private int currIndex = 0;
public Queue(int capacity) {
data = new Object[capacity];
this.capacity = capacity;
}
public int size() {
return size;
}
public void push(Object obj) {
if(size > MAX_SIZE) {
throw new IllegalArgumentException("over max size....");
}
if(size <= capacity) {
if(currHead == 0) { //如果還沒有pop過
data[size++] = obj;
} else{
if(capacity - currHead == size) { //如果隊列後面已經滿了
data[currIndex++] = obj;
size++;
} else {
data[++size] = obj;
}
}
}
}
public Object pop() {
--size;
if(size >= 0) {
if(currHead == capacity) {
currHead = 0;
}
Object value = data[currHead];
data[currHead] = null;
currHead++;
return value;
}
return null;
}
}