需要傳入數組大小
定義了頭指針和尾指針
我的:
public int Maxsize;
private int front;
private int rear;
private Object[] Arr;
public ArrQueue(int ArrMaxsize) {
Maxsize = ArrMaxsize;
Arr = new Object[Maxsize];
front = -1;
rear = -1;
}
最初,頭指針和尾指針都指向-1
Java jdk:
//它也是傳入數組的大小,並且有異常提示
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
入隊
我的:
public void In_ArrQueue(Object obj){
if(rear >= Maxsize-1){ //超界
System.out.println("隊滿!!!");
}
else{
rear++; //隊尾指針上移
Arr[rear] = obj; //元素加到隊尾(後進後出)
}
}
Java jdk包裏面的就牛逼了,它用到了資源申請算法。。。
Java jdk:
public boolean add(E e) {
ensureCapacityInternal(size + 1);
elementData[size++] = e; //元素入隊
return true;
}
////////後面的一大堆方法全是關於申請合理的數組容量的
private static final int DEFAULT_CAPACITY = 10;
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
//minCapacity 就是需要的最小的容量
private void ensureCapacityInternal(int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { //若數組爲空
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); //分配大小爲10
}
ensureExplicitCapacity(minCapacity);
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
if (minCapacity - elementData.length > 0) //需要的容量比擁有的大(添加數組後若越界)
grow(minCapacity); //增加擁有的容量
}
private void grow(int minCapacity) {
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1); //相當於oldCapacity的1.5倍
if (newCapacity - minCapacity < 0) //如果新容量比需要的還要小
newCapacity = minCapacity; //賦值
if (newCapacity - MAX_ARRAY_SIZE > 0) //合理性檢查
newCapacity = hugeCapacity(minCapacity);
elementData = Arrays.copyOf(elementData, newCapacity);
}
private static int hugeCapacity(int minCapacity) { //檢測異常
//小於0代表minCapacity溢出
if (minCapacity < 0)
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE;
}
下面來對比一下性能(莫名感覺很慚愧。。。):
//仍然是比較加入一千萬個點的時間
public static void main(String[] args) {
long S = 0;
for (int n = 0; n < 10; n++) {
long start = System.currentTimeMillis();
ArrayList<Object> arrayList = new ArrayList<>();
for (int i = 0; i < 10000000; i++) {
arrayList.add(i);
}
long end = System.currentTimeMillis();
System.out.println(end - start);
long S1 = end - start;
S = S + S1;
}
System.out.println("平均時間" + S / 10);
我的:
系統:
- 我的add方法之所以快,是因爲我一開始就定義好了數組的長度,這樣其實是浪費了大量的空間
- 系統通過資源申請算法,很完美的控制了空間資源分配,實現了利用數組創建隊列不需要定義長度
- (今天的操作系統課剛好講了銀行家算法中的資源請求算法,這就用上了,,,)
出隊
我的:
public void Out_ArrQueue(){
if(rear == front){
System.out.println("隊空!!!");
}
else{
front++; //出隊時隊首指針上移 (假溢出的部分根源)
Arr[front]=null;
}
}
Java jdk:
E elementData(int index) { //返回index位置的元素
return (E) elementData[index];
}
private void rangeCheck(int index) { //檢測範圍異常
if (index >= size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
public static native void arraycopy(Object src, int srcPos,
Object dest, int destPos,
int length);
public E remove(int index) { //jdk中要傳入一個下標
rangeCheck(index); //是否超界
modCount++;
E oldValue = elementData(index); //獲取該位置元素
int numMoved = size - index - 1; //被刪除位置的元素之後的元素要前移
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index, numMoved); //拷貝移動元素
elementData[--size] = null; //如果後面沒要移的元素,說明是個尾節點
return oldValue; //返回要刪除的值(Object a = arrayList.remove(i))
}
分析完系統的代碼,下面的測試根本就沒有必要去測了,,,我感覺無比慚愧,自己寫的代碼就是渣。。。
我的運行時間(一千萬數):
系統運行時間(十萬個數):
- 系統是從指定位置刪除元素的
查詢
我的:
public void Find(int index){
System.out.println(Arr[index]);
}
Java jdk:
public E get(int index) {
rangeCheck(index); //檢測是否越界
return elementData(index); //返回值
}
- 查詢功能,因爲大家用的都是數組,所以就比較簡單,查詢就很快
- Java jdk多了一個檢測異常
- 以後寫代碼儘量養成這種檢測異常的習慣
一千萬個點:
添加元素,利用了資源申請算法
刪除元素,系統可以從指定位置刪除
每一種方法,系統都有異常檢測