B2.2 資料結構
資料結構(Data structures)是在程式中組織與儲存多筆資料的方式。本頁說明靜態與動態資料結構的差別、一維與二維陣列(串列)的操作,以及堆疊與佇列的基本概念。HL 會在 B4 抽象資料型別 中進一步實作這些結構。
靜態與動態資料結構有什麼不同?
| 比較 | 靜態(static) | 動態(dynamic) |
|---|---|---|
| 大小 | 建立時固定 | 執行時可增減 |
| 記憶體 | 一次配置,可能浪費或不足 | 依需求配置,較有效率 |
| 存取速度 | 連續記憶體,索引存取很快 | 依實作而定 |
| 例子 | Java 陣列 int[10] |
Python list、Java ArrayList、鏈結串列 |
一維陣列如何操作?
陣列(array)把相同用途的資料依序存放,用索引存取,索引從 0 開始。
int[] scores = {6, 4, 7, 5}; // 靜態陣列,長度固定為 4
scores[1] = 5;
int total = 0;
for (int i = 0; i < scores.length; i++) {
total += scores[i];
}
System.out.println((double) total / scores.length);
// 需要可變長度時用 ArrayList
ArrayList<Integer> list = new ArrayList<>();
list.add(6);
list.add(4);
list.remove(Integer.valueOf(6));
二維陣列如何操作?
二維陣列(2D array)像表格,用 [列][行] 存取,常用來表示成績表、棋盤、圖片像素。
int[][] grades = {
{5, 6, 7, 6},
{4, 4, 5, 6},
{7, 7, 6, 7}
};
System.out.println(grades[1][2]); // 5
for (int r = 0; r < grades.length; r++) {
int sum = 0;
for (int c = 0; c < grades[r].length; c++) {
sum += grades[r][c];
}
System.out.printf("學生 %d: 平均 %.2f%n", r, (double) sum / grades[r].length);
}
堆疊和佇列有什麼不同?
- 堆疊(stack):後進先出(Last In, First Out, LIFO),像一疊盤子,只能從頂端放(push)與拿(pop)。用途:瀏覽器「上一頁」、復原(undo)、函式呼叫、括號配對檢查。
- 佇列(queue):先進先出(First In, First Out, FIFO),像排隊,從尾端加入(enqueue)、從前端取出(dequeue)。用途:印表機工作排程、CPU 排程、鍵盤緩衝區。
from collections import deque
stack = []
stack.append("A"); stack.append("B")
print(stack.pop()) # B(最後放的先出)
queue = deque()
queue.append("A"); queue.append("B")
print(queue.popleft()) # A(最先放的先出)
還有哪些內建資料結構?
- 字典(dictionary/map):用鍵(key)對應值,查詢很快。Python
dict、JavaHashMap。 - 集合(set):不重複元素的集合,適合去除重複或檢查是否存在。
student = {"id": 101, "name": "Amy", "level": "HL"}
print(student["name"]) # Amy
tags = {"python", "java", "python"}
print(tags) # {'python', 'java'}
推薦影音
資料結構
簡述:Crash Course 介紹陣列、字串、矩陣、鏈結串列、堆疊、佇列、樹與圖,用動畫說明每種結構在記憶體中的樣子,是本頁與 B4 的共同入門。
堆疊與佇列(HackerRank)
簡述:《Cracking the Coding Interview》作者 Gayle Laakmann McDowell 說明堆疊與佇列的操作與實作方式,對應本頁堆疊與佇列一節。
練習題
練習 1:陣列操作
寫一個函式 count_above(scores, limit),回傳串列中大於 limit 的元素個數。
練習 2:二維陣列
使用本頁的 grades 二維陣列,寫程式計算 每次考試(每一行)的平均分數。
練習 3:堆疊或佇列
下列情境各適合堆疊還是佇列:(a) 客服電話等待系統;(b) 文字編輯器的 Ctrl+Z;(c) 檢查 ((a+b)*c) 括號是否配對。
參考答案
(a) 佇列,先打來的先服務;(b) 堆疊,最近的動作最先被復原;(c) 堆疊,遇到 ( 就 push,遇到 ) 就 pop,最後堆疊為空才配對。
練習 4:預測堆疊輸出
依序執行 push 1、push 2、pop、push 3、push 4、pop、pop,pop 出來的值依序是什麼?堆疊最後剩下什麼?
參考答案
pop 依序為 2、4、3,最後堆疊剩下 [1]。