一、Stack (棧)
1、資料結構
Stack是棧。它的特性是:先進後出(FILO, First In Last Out) 後進先出(Last in - First out)。java工具包中的Stack是繼承於Vector(向量佇列)的,由於Vector是通過陣列實現的,這就意味著,Stack也是通過陣列實現的,而非連結串列。當然,我們也可以將LinkedList當作棧來使用。
2、Stack的繼承關係
3、時間複雜度
操作 | 時間複雜度 |
---|---|
lookup | O(n) |
insert | O(1) |
delete | O(1) |
4、原始碼實現
Stack
繼承自 Vector
底層為動態陣列實現
/**
* 向棧頂新增元素
* Pushes an item onto the top of this stack. This has exactly
* the same effect as:
* <blockquote><pre>
* addElement(item)</pre></blockquote>
*
* @param item the item to be pushed onto this stack.
* @return the <code>item</code> argument.
* @see java.util.Vector#addElement
*/
public E push(E item) {
addElement(item); // Vector 中的新增方法
return item;
}
/**
* Removes the object at the top of this stack and returns that
* object as the value of this function.
* 檢視棧頂元素並刪除
* @return The object at the top of this stack (the last item
* of the <tt>Vector</tt> object).
* @throws EmptyStackException if this stack is empty.
*/
public synchronized E pop() {
E obj;
int len = size();
obj = peek();
removeElementAt(len - 1); // Vector 中的按照下標移除元素的方法
return obj;
}
/**
* Looks at the object at the top of this stack without removing it
* from the stack.
* 檢視棧頂元素但不刪除
* @return the object at the top of this stack (the last item
* of the <tt>Vector</tt> object).
* @throws EmptyStackException if this stack is empty.
*/
public synchronized E peek() {
int len = size();
if (len == 0)
throw new EmptyStackException();
return elementAt(len - 1);
}
// 棧是否為空
public boolean empty() {
return size() == 0;
}
// 查詢“元素o”在棧中的位置:由棧底向棧頂方向數
public synchronized int search(Object o) {
// 獲取元素索引,elementAt()具體實現在Vector.java中
int i = lastIndexOf(o);
if (i >= 0) {
return size() - i;
}
return -1;
}
二、Queue (佇列)
1、資料結構
First in - First out(先進先出 FIFO)
2、時間複雜度
操作 | 時間複雜度 |
---|---|
lookup | O(n) |
insert | O(1) |
delete | O(1) |
3、原始碼實現
//介面Queue:
public interface Queue<E> extends Collection<E> {
//將指定元素插入到佇列的尾部(佇列滿了話,會丟擲異常)
boolean add(E e);
//將指定元素插入此佇列的尾部(佇列滿了話,會返回false)
boolean offer(E e);
/返回取佇列頭部的元素,並刪除該元素(如果佇列為空,則丟擲異常)
E remove();
//返回佇列頭部的元素,並刪除該元素(如果佇列為空,則返回null)
E poll();
//返回佇列頭部的元素,不刪除該元素(如果佇列為空,則丟擲異常)
E element();
//返回佇列頭部的元素,不刪除該元素(如果佇列為空,則返回null)
E peek();
}
三、Deque (Double-Ended Queue 雙端佇列)
1、資料結構
線性集合,支援兩端插入和移除元素。名稱deque是“雙端佇列(double ended queue)”的縮寫。
也可以理解為 Queue 與 Stack 的結合體,可以從頭部 Push 或者 Pop 元素,也可以在尾部 Push 或者 Pop 元素,兩端可以進出的佇列
2、Deque 的繼承關係
3、方法摘要
First Element (Head) | Last Element (Tail) | |||
Throws exception | Special value | Throws exception | Special value | |
Insert(插入操作) | addFirst(e) |
offerFirst(e) |
addLast(e) |
offerLast(e) |
Remove(移除操作) | removeFirst() |
pollFirst() |
removeLast() |
pollLast() |
Examine(檢索操作) | getFirst() |
peekFirst() |
getLast() |
peekLast() |
4、時間複雜度
操作 | 時間複雜度 |
---|---|
lookup | O(n) |
insert | O(1) |
delete | O(1) |
5、原始碼實現
四、Priority Queue (優先佇列)?️
1、資料結構
底層具體實現的資料結構較為多樣和複雜可以使用 heap、bst(binary search tree)、treap
2、時間複雜度
操作 | 時間複雜度 |
---|---|
插入 | O(1) |
取出 | O(logN) |
3、原始碼實現 & 文件
它的使用與佇列幾乎沒有區別,只不過我們在取元素的時候需要注意都是取優先順序最高的,優先順序怎麼定義?我們只需要將元素取實現 comparator
(比較器)就可以由大到小
或由小到大
再或者 自己定義某個欄位優先等等。
Java 的 PriorityQueue 文件
Java 的 PriorityQueue 原始碼