public interface IList<T> {
boolean isEmpty();
int length();
T get(int i);
void set(int i, T x);
void append(T x);
T remove(int i);
void removeAll();
T search(T key);
void insert(int i, T x);
void insert(T x); // 有序插入
void remove(T x); // 有序刪除
}
private Object[] elements; // 底層數組
private int size; // 當前長度
System.arraycopy 遷移i 及之後元素**向後移動**,再賦值 elements[i]=x,size++i+1 及之後元素**向前移動**,size--O(1) 直接索引| 操作 | 時間復雜度 | 說明 |
|---|---|---|
| get/set | O(1) | 隨機訪問優勢 |
| insert/remove | O(n) | 需移動大量元素,平均移動 n/2 |
| 擴容 | O(n) | 偶發觸發,均攤 O(1) |
結論:**靜態查詢快,動態增刪慢**,適合「讀多寫少」場景。
class Node<T> {
T data;
Node<T> next;
Node(T d, Node<T> n) { data=d; next=n; }
}
帶**頭節點**簡化邊界處理:head.next 指向首元素。
O(n)i+1 步 O(n)i-1 個節點 p,p.next = new Node(x, p.next) O(1) (不含查找)i-1 個節點 p,p.next = p.next.next O(1) (不含查找)insert(MAX_VALUE, x) 利用循環終止條件自然插到尾部Comparable<T>p.next.data >= x 的前驅 p,插入其後p.next.data == x 的前驅 p,刪除 p.next
class DNode<T> {
T data;
DNode<T> prev, next;
}
head.next == head && head.prev == headprev 和 next 兩個方向| 操作 | 順序表 | 單鏈表 | 雙向鏈表 |
|---|---|---|---|
| 隨機訪問 | O(1) ✓ | O(n) | O(n) |
| 指定位置插入/刪除 | O(n) 移動 | O(1) 改鏈 (含查找 O(n)) | O(1) 改鏈 |
| 僅知節點插入/刪除 | 不可行 | O(1) 僅單向 | O(1) 雙向 ✓ |
| 內存開銷 | 連續,無指針 | 每節點 1 指針 | 每節點 2 指針 |
| 擴容 | 需遷移 | 無需預分配 | 無需預分配 |
ArrayList 底層即順序表,LinkedList 為雙向鏈表ArrayList;高頻首尾增刪/中間迭代器操作 → LinkedList