本文的主要內容就是利用數組[]實現雙向隊列,當然,Java中有比較豐富的容器可以直接使用,實現類似的功能容器有助於我們更深入的學習好了解相關知識。
現在就開始一步一步講解如何實現。
1、雙向隊列的功能
首先,我們既然要實現該功能,就必然要把需求梳理清楚,我們要實現的容器到底有哪些功能。我們實現的隊列主要功能如下:
入隊列(push)
出隊列(pop)
隊首入隊列(unshift)
隊首出隊列(shift)
獲取隊列中某個元素(get)
將值插入隊列某個位置(insert)
移除隊列中指定位置的值(remove)
迭代器(iterator) 所以,我們可以定義隊列的接口如下:
package LinearList;
import java.util.Iterator;
public interface LinearList<E> {
//獲取隊列指定位置元素
public E get(int i);
//獲取隊列長度
public int getSize();
//判斷隊列是否爲空
public boolean isEmpty();
//隊列指定位置插入元素
public boolean insert(int i, E o);
//移除指定位置元素
public boolean remove(int i);
//隊尾入隊列
public boolean push(E o);
//隊首入隊列
public boolean unshift(E o);
//隊尾出隊列
public E pop();
//隊首出隊列
public E shift();
//迭代器
public Iterator<E> iterator();
}
定義了一個泛型接口,方法含義已在代碼中註釋,不解釋了。 下面就貼出具體實現類,並解釋其含義。
package LinearList.imp;
import LinearList.*;
import com.sun.istack.internal.NotNull;
import java.util.*;
/**
* 數組實現線性表
* author: xubaodian
* time: 2018/9/25
* @param
*/
public class ArrayLinearList<E> implements LinearList<E> {
//採用數組實現隊列,初始數組長度爲8,
private int Len = 8;
//隊列長度,隊列長度小於等於數據長度
private int count = 0;
//數組,是隊列的容器,用來保存隊列元素
private Object []arrayList;
public ArrayLinearList() {
arrayList = new Object[this.Len];
}
//獲取隊列中的指定元素,若索引大於隊列長度,則拋出異常
@Override
public E get(int i) {
if (i < this.count) {
return (E)this.arrayList[i];
} else {
throw new ArrayIndexOutOfBoundsException("索引超出隊列長度");
}
}
//獲取隊列長度
@Override
public int getSize() {
return this.count;
}
//判斷隊列是否爲空
@Override
public boolean isEmpty() {
if (this.count == 0) {
return true;
}
return false;
}
//隊列指定位置插入元素
@Override
public boolean insert(int i, E o) {
if (i <= this.count) {
for(int j = this.count; j > i ; j--) {
this.arrayList[j] = this.arrayList[j - 1];
}
this.arrayList[i] = o;
this.count++;
this.expandArray();
return true;
} else {
throw new ArrayIndexOutOfBoundsException("索引超出隊列長度");
}
}
//移除指定位置元素
@Override
public boolean remove(int i) {
if (i < this.count) {
for (int j = i; i < this.count - 1; j++) {
this.arrayList[j] = this.arrayList[j + 1];
}
this.count--;
return true;
} else {
throw new ArrayIndexOutOfBoundsException("索引超出隊列長度");
}
}
//隊尾壓入數組
@Override
public boolean push(E o) {
this.arrayList[this.count++] = o;
this.expandArray();
return true;
}
//隊首壓入數組
@Override
public boolean unshift(E o) {
for(int i = this.count; i > 0; i--) {
this.arrayList[i] = this.arrayList[i - 1];
}
this.count++;
this.arrayList[0] = o;
this.expandArray();
return true;
}
//隊尾出數組
@Override
public E pop() {
if (this.count > 0) {
return (E)this.arrayList[this.count--];
} else {
return null;
}
}
//隊首出數組
@Override
public E shift() {
if (this.count > 0) {
Object tmp = this.arrayList[0];
for (int i = 0; i < this.count; i++) {
this.arrayList[0] = this.arrayList[i + 1];
}
this.count--;
return (E)tmp;
} else {
return null;
}
}
//數組容量擴充爲原來的2倍,並將現有數組遷移入新的數組中
private void expand() {
this.Len *= 2;
Object [] array = new Object[this.Len];
for (int i = 0; i < count; i++) {
array[i] = this.arrayList[i];
}
this.arrayList = array;
}
//判斷數組是否已滿,若數組已滿,則擴充數組
private void expandArray() {
if (this.count == this.Len) {
this.expand();
}
}
//返回迭代器
@Override
@NotNull
public Iterator<E> iterator() {
return new ArrayLinearList.Itr();
}
//迭代器私有類
private class Itr implements Iterator<E> {
int cursor = 0; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
public boolean hasNext() {
return cursor != count;
}
@SuppressWarnings("unchecked")
public E next() {
int i = cursor;
if (i >= count)
throw new NoSuchElementException();
cursor = i + 1;
return (E) arrayList[lastRet = i];
}
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
try {
ArrayLinearList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
}
}
利用數組實現隊列,數組的初始長度爲8,當數組已滿,則新建數組,新數組容量爲現有數字的2倍,並將現有數組元素遷移至新數組。
同時,爲隊列實現了跌代器,利用跌代器可遍歷容器。
具體實現並不難,大家可根據代碼,理解一下,有利於理解java容器知識,如有疑問,請給我留言。