Data structure
Lecture by howard41436
Credit by music960633
2019/03/08
課程內容
• 0. 什麼是資料結構
• 1. stack
• 2. queue
• 3. linked list
為什麼要學資料結構
• 資料結構:如何在電腦中儲存資料
• 對於不同用途選擇不同資料結構
• 時間複雜度
• 空間複雜度
• coding複雜度
• 資料結構是一種工具
• (多種)演算法+(多種)資料結構
為什麼要學資料結構
為什麼要學資料結構
• 資料結構:如何在電腦中儲存資料
• 對於不同用途選擇不同資料結構
• 時間複雜度
• 空間複雜度
• coding複雜度
• 資料結構是一種工具
• (多種)演算法+(多種)資料結構
常見的資料結構操作
• push : 放進一個元素
• pop : 拿出一個元素
• query: 各種查詢
stack
• 堆疊
• 性質
• first in last out (FILO)
• 疊盤子
• 基本操作
• push:把一個元素放進stack
• pop :把一個元素拿出stack
stack
• 實做
• 使用陣列或linked list
• 陣列實做
• 用一個變數top記錄頂端的位置
• top=-1: stack是空的
• push: top加1
• pop : top減1
stack
stack 結果
操作
top
stack
stack 結果
操作
push 1
top
stack
stack
1 結果
操作
push 1
top
stack
stack
1 結果
操作
push 1
push 2
top
stack
stack
2 1 結果
操作
push 1
push 2
top
stack
stack
2 1 結果
操作
push 1
push 2
pop
top
stack
stack
1 結果
2
操作
push 1
push 2
pop
top
stack
stack
1 結果
2
操作
push 1
push 2
pop
push 3
top
stack
stack
3 1 結果
2
操作
push 1
push 2
pop
push 3
top
stack
stack
3 1 結果
2
操作
push 1
push 2
pop
push 3
pop
top
stack
stack
1 結果
2
3
操作
push 1
push 2
pop
push 3
pop
top
stack
stack
1 結果
2
3
操作
push 1
push 2
pop
push 3
pop
pop
top
stack
stack 結果
2
3
1
操作
push 1
push 2
pop
push 3
pop
pop
top
queue
• 佇列
• 性質
• first in first out (FIFO)
• 排隊
• 分類:單向、環狀
• 基本操作
• push:把一個元素放進queue
• pop :把一個元素拿出queue
queue
• 實做
• 使用陣列或linked list
• 陣列實做
• 用一個變數front記錄最前面的元素的「前一格」位置
• 用一個變數rear 記錄最後面的元素的位置
• front==rear: queue是空的
• push: rear 加1
• pop : front加1
queue
queue 結果
操作
front=rear
queue
queue 結果
操作
push 1
front=rear
queue
queue
1 結果
操作
push 1
rear
front
queue
queue
1 結果
操作
push 1
push 2
rear
front
queue
queue
2 1 結果
操作
push 1
push 2
rear
front
queue
queue
2 1 結果
操作
push 1
push 2
pop
rear
front
queue
queue
2 結果
1
操作
push 1
push 2
pop
rear
front
queue
queue
2 結果
1
操作
push 1
push 2
pop
push 3
rear
front
queue
queue
3 2 結果
1
操作
push 1
push 2
pop
push 3
rear
front
queue
queue
3 2 結果
1
操作
push 1
push 2
pop
push 3
pop
rear
front
queue
queue
3 結果
1
2
操作
push 1
push 2
pop
push 3
pop
rear
front
queue
queue
3 操作
push 1
push 2
pop
push 3
pop
pop
結果
1
2
rear
front
queue
queue 結果
1
2
3
操作
push 1
push 2
pop
push 3
pop
pop
front=rear
queue
• 產生的問題
• 一個元素一旦被pop,該位置無法再放新的元素
• 解決方法
• rear到陣列最後的時候,將所有元素平移到前方
• 使用環狀queue
• 使用linked list
queue
front
queue 5 4 操作
...
...
...
push 6
rear
方法一
queue
queue
5 4 操作
...
...
...
push 6
方法一
front
rear
queue
queue
6 5 4 操作
...
...
...
push 6
方法一
front
rear
queue
front
queue 5 4 操作
...
...
...
push 6
rear
方法二
queue
front
queue 5 4
6 操作
...
...
...
push 6
rear
方法二
時間複雜度
push pop
stack O(1) O(1)
queue O(1) O(1)
Practice
• Try Homework Q36, 37
linked list
• 鏈結串列
• 基本單元:Node(data + pointer)
• 將很多Node接起來
• head指標指向第一個Node,最後一個指標指向NULL
data data NULL
head data
linked list
• 性質
• 每個元素只記錄他的下一個元素,外部只記錄起點(head)
• 動態宣告記憶體
• 分類:單向、雙向、環狀
• 不能隨機存取(random access)
• 基本操作
• insert: 在兩個元素中插入一個元素,或是在頭尾插入元素
• delete: 刪除一個元素
linked list
• 實做
• 先定義一個struct/class Node,作為linked list的節點,裡面存資 訊和一個指向下一個Node的指標
• 使用時只用一個變數head記錄linked list的起點就可以了
linked list
• 為什麼要這麼麻煩,用陣列不就好了(還能random access)?
• 1. 避免記憶體浪費
• dynamic array也可以做啊(ex: stl的vector)
• 2. 可以快速的插入和刪除節點!
• array無法做到
linked list
• insert
data head
data
data NULL
linked list
• delete
data
head data data NULL
linked list
• 用linked list實做stack
• 用linked list實做queue
linked list
• 用linked list實做stack
• push: 在head前面插入一個節點
• pop : 刪除head指向的節點
• 用linked list實做queue
• 還要多記錄linked list的尾端(end)
• push: 在end後面插入一個節點
• pop : 刪除head指向的節點
linked list
• 雙向
• 環狀
data data data
data data
head data
時間複雜度
random access
push front
push back
pop front
pop back
Array Yes O(n) O(1) O(n) O(1)
Linked list
No O(1) O(1) O(1) O(1)
例題思考1 – 括弧匹配
• 給一個括弧字串,判斷他是否合法
• ([]){} -> 合法
• {([[]]))} -> 不合法
• What should we do?
例題思考1 – 括弧匹配
• Sol 1: 數數
• 數有幾個左 幾個右就好
• {([)]} ?
例題思考1 – 括弧匹配
• Sol 1: 數數
• 數有幾個左 幾個右就好
• {([)]} ?
例題思考1 – 括弧匹配
• STACK!!!