軟體工程師職涯升級計畫啟動!立即預約職涯諮詢、履歷健檢或模擬面試👈,為您的加薪做好準備!
在學習演算法與資料結構的路上,理解「資料如何儲存與操作」是關鍵起點。最近參加了 AC 演算法專攻班,課程即將邁入尾聲,收穫滿滿。這次免費課程讓我真正掌握了演算法的核心觀念,尤其在解題時的邏輯與資料結構選擇,對我影響很深。
趁熱打鐵,紀錄下「Array 陣列」與「Linked List 串列」這兩個基礎資料結構的學習筆記與比較,並補充 JS 範例與常見使用情境。
🔑 學習重點整理
重點說明- 結構: 語言是否內建?可否自行實作?
- 特性: 優缺點、適合場景
- 方法: 常見 API + 時間複雜度分析
一、📦 Array 陣列

✅ 結構
- 幾乎所有語言皆內建,如 JavaScript、Python、C++。
- 字串本質上也是一種字元陣列。
✅ 特性
- 支援隨機存取
array[index]
,時間複雜度 O(1)。 - 記憶體連續配置、空間利用率高。
✅ 常見操作與時間複雜度

📌 補充知識
- 陣列可透過記憶體 offset 快速定位。
- JavaScript
push()
、unshift()
等方法本質上仍會觸發搬移或 resize 操作。
✅ JavaScript 實作
js
複製編輯class ArrayDemo {
constructor() {
this.arr = [];
}
get(index) {
return this.arr[index];
}
insertAtEnd(value) {
this.arr.push(value);
}
insertAtFront(value) {
this.arr.unshift(value);
}
delete(index) {
this.arr.splice(index, 1);
}
binarySearch(target) {
let left = 0, right = this.arr.length - 1;
while (left <= right) {
const mid = Math.floor((left + right) / 2);
if (this.arr[mid] === target) return mid;
if (this.arr[mid] < target) left = mid + 1;
else right = mid - 1;
}
return -1;
}
print() {
console.log(this.arr);
}
}
// 🧪 測試
const a = new ArrayDemo();
a.insertAtEnd(3);
a.insertAtEnd(5);
a.insertAtFront(1);
a.print(); // [1, 3, 5]
console.log(a.get(1)); // 3
a.delete(1);
a.print(); // [1, 5]
console.log(a.binarySearch(5)); // 1(前提是已排序)
二、🔗 Linked List 串列

✅ 結構
- 每個節點(node)由資料與指標組成。
- 指標指向下一個節點。
text
複製編輯[1] → [2] → [3] → null
✅ 特性
- 插入刪除:不需搬移,調整指標即可。
- 存取需從頭依序走訪,無隨機存取功能。
✅ 常見操作與時間複雜度

✅ JavaScript 實作
js
複製編輯class Node {
constructor(value) {
this.value = value;
this.next = null;
}
}
class LinkedList {
constructor() {
this.head = null;
}
insertAtFirst(value) {
const newNode = new Node(value);
newNode.next = this.head;
this.head = newNode;
}
insertAtEnd(value) {
const newNode = new Node(value);
if (!this.head) {
this.head = newNode;
return;
}
let current = this.head;
while (current.next) current = current.next;
current.next = newNode;
}
deleteAtHead() {
if (this.head) this.head = this.head.next;
}
delete(value) {
if (!this.head) return;
if (this.head.value === value) {
this.head = this.head.next;
return;
}
let current = this.head;
while (current.next && current.next.value !== value) {
current = current.next;
}
if (current.next) current.next = current.next.next;
}
search(value) {
let current = this.head, index = 0;
while (current) {
if (current.value === value) return index;
current = current.next;
index++;
}
return -1;
}
print() {
const result = [];
let current = this.head;
while (current) {
result.push(current.value);
current = current.next;
}
console.log(result);
}
}
// 🧪 測試
const list = new LinkedList();
list.insertAtFirst(3);
list.insertAtFirst(1);
list.insertAtEnd(5);
list.print(); // [1, 3, 5]
console.log(list.search(3)); // 1
list.delete(3);
list.print(); // [1, 5]
list.deleteAtHead();
list.print(); // [5]
三、🆚 陣列 vs 串列

四、📌 何時選哪個?

🧠 延伸資源
這兩種基礎資料結構,看似簡單,但實際運用與演算法搭配時,會發現每一個選擇背後都藏著複雜的 trade-off。理解這些基本觀念,不僅能幫助寫出高效的程式,也能在面對不同題型時做出正確選擇。