模仿 ArrayList 實作一個泛型順序表 SequenceList<T>,用於理解動態陣列的擴容、插入刪除位移等核心機制。
Object[] elementData 儲存元素。capacity 記錄陣列容量,size 記錄當前元素數。add、insert、delete、get、locate 等基本操作。import java.util.Arrays;
public class SequenceList<T> {
private final int DEFAULT_SIZE = 16;
private int capacity;
private Object[] elementData;
private int size = 0;
public SequenceList() {
capacity = DEFAULT_SIZE;
elementData = new Object[capacity];
}
public SequenceList(T element) {
this();
elementData[0] = element;
size++;
}
public SequenceList(T element, int initSize) {
capacity = 1;
while (capacity < initSize) capacity <<= 1; // 擴展為 2 的冪次
elementData = new Object[capacity];
elementData[0] = element;
size++;
}
public int length() { return size; }
public T get(int i) {
if (i < 0 || i > size - 1) throw new IndexOutOfBoundsException("索引越界");
return (T) elementData[i];
}
public int locate(T element) {
for (int i = 0; i < size; i++)
if (elementData[i].equals(element)) return i;
return -1;
}
public void insert(T element, int index) {
if (index < 0 || index > size) throw new IndexOutOfBoundsException("索引越界");
ensureCapacity(size + 1);
System.arraycopy(elementData, index, elementData, index + 1, size - index);
elementData[index] = element;
size++;
}
public void add(T element) { insert(element, size); }
private void ensureCapacity(int minCapacity) {
if (minCapacity > capacity) {
while (capacity < minCapacity) capacity <<= 1;
elementData = Arrays.copyOf(elementData, capacity);
}
}
public T delete(int index) {
if (index < 0 || index > size - 1) throw new IndexOutOfBoundsException("索引越界");
T oldValue = (T) elementData[index];
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index + 1, elementData, index, numMoved);
elementData[--size] = null; // 釋放引用助 GC
return oldValue;
}
public T remove() { return delete(size - 1); }
public boolean empty() { return size == 0; }
public void clear() {
Arrays.fill(elementData, null);
size = 0;
}
@Override
public String toString() {
if (size == 0) return "[]";
StringBuilder sb = new StringBuilder("[");
for (int i = 0; i < size; i++) sb.append(elementData[i]).append(", ");
return sb.delete(sb.length() - 2, sb.length()).append("]").toString();
}
}
| 操作 | 時間複雜度 | 說明 |
|---|---|---|
| 隨機存取 (get) | O(1) | 陣列下標直接定位 |
| 尾部新增 (add) | O(1) 攤還 | 偶爾觸發擴容複製 |
| 中間插入/刪除 | O(n) | 需移動後續所有元素 |
| 擴容 | O(n) | 建立 2 倍新陣列並複製 |