• 沒有找到結果。

Data Structure

N/A
N/A
Protected

Academic year: 2022

Share "Data Structure"

Copied!
67
0
0

加載中.... (立即查看全文)

全文

(1)

Data Structure

Lecture by casperwang 2022/03/05

(2)

課程內容

● 什麼是資料結構?

● Stack

● Queue

● Deque

● Linked-list

● 例題討論

(3)

什麼是資料結構?

(4)

資料結構

● 是電腦中儲存、組織資料的方式

● 好的資料處理方式,能讓程式節省時間與空間

● 例如:「陣列」就是一種資料結構

(5)

Why 資料結構?

Algorithms + Data Structures

= Programs

Niklaus Wirth, the designer of Pascal

(6)

常見的資料結構

● Stack, Queue, Deque

● Linked-list

● Heap

● Set, Map

● Disjoint Set

● Bit, Segment Tree, Sparse Table

● ……

(7)

Stack

(8)

Stack

● 要怎麼拿到紫色的那本書?

(9)

Stack

● 要怎麼拿到紫色的那本書?

先依序把橘、黃、紅的書拿起來 拿到紫色的書

再依序將紅、黃、橘的書放回去

(10)

Stack(堆疊)

Empty

(11)

Stack(堆疊)

加入新資料

1

(12)

Stack(堆疊)

加入新資料

1 2

(13)

Stack(堆疊)

刪除最頂端資料

1

(14)

Stack(堆疊)

加入新資料

1 3

(15)

Stack(堆疊)

加入新資料

1 3 4

(16)

Stack(堆疊)

刪除最頂端資料

1 3

(17)

Stack(堆疊)

刪除最頂端資料

1

(18)

Stack 的功能

● 存取排在 stack 最頂端的資料

● 刪除排在 stack 最頂端的資料

● 新增資料到 stack 的最頂端

(19)

Stack 的特性

● 只能從最頂端存取、刪除、新增資料

● 後進先出(Last In First Out, LIFO)

(20)

用陣列實作 Stack

● top() 回傳 stack 最頂端的值

● pop() 刪除 stack 最頂端的資料

● push() 將一個新的值加入 stack

● size() 回傳 stack 的大小

(21)

用陣列代表 Stack

● 假設任意時刻 stack 裡的資料筆數不會超過陣列大小

(22)

用變數 now 記錄頂端位置

● 如果 now = 0,代表 stack 是空的

● push 時 now++

● pop 時 now--

(23)
(24)

Queue

(25)

Queue

● 先到的先拿!

(26)

Queue(佇列)

(27)

Queue 的功能

● 存取排在 queue 最前端的資料

● 刪除排在 queue 最前端的資料

● 新增資料到 queue 的最後端

(28)

Queue 的特性

● 只能從最前端存取、刪除資料

● 只能從最後端新增資料

● 先進先出(First In First Out, FIFO)

(29)

用陣列實作 Queue

● front() 回傳 queue 最前端的值

● pop() 刪除 queue 最前端的資料

● push() 將一個新的值加入 queue 的最後端

● size() 回傳 queue 的大小

(30)

和 stack 類似的方法

● 用變數 head, tail 記錄目前 queue 的開頭、結尾

● push 時 tail++

● pop 時 head++

(31)

和 stack 類似的方法

● 用變數 head, tail 記錄目前 queue 的開頭、結尾

● push 時 tail++

● pop 時 head++

(32)

但...可能會碰到問題

● 如果一直 push 東西進去後立刻 pop 出來?

(33)

但...可能會碰到問題

● 如果一直 push 東西進去後立刻 pop 出來?

● 雖然在過程中 queue 所存的東西數量不會超過上限,但?

(34)

Circular Queue

● 如果不斷進行 push 然後 pop 的操作會超過陣列限制

(35)

Circular Queue

● 如果不斷進行 push 然後 pop 的操作會超過陣列限制

● 碰到尾巴的話,就從頭再來一次!

(36)
(37)

Deque

(38)

Deque(雙端佇列)

● 有些人喜歡念成「de-queue」

(39)

Deque(雙端佇列)

● 有些人喜歡念成「de-queue」

● usually pronounced like "deck" —— by CPP reference

(40)

Deque 的功能

● 存取、刪除排在 deque 最前端的資料

● 存取、刪除排在 deque 最後端的資料

● 新增資料到 deque 的最前端、最後端

(41)

用陣列實作 Deque

● front(), back() 詢問

● pop_front(), pop_back() 刪除

● push_front(), push_back() 加入

● size()

(42)
(43)

Linked-list

(44)

Linked-list 的概念

● 對於每個資料紀錄前後資料的位置

● 可以 O(1) 加入、刪除特定資料

● 不支援 random-access

○ 不能 O(1) 存取指定 index 的資料

(45)

Linked-list 的概念

● 對於每個資料紀錄前後資料的位置

● 可以 O(1) 加入、刪除特定資料

● 不支援 random-access

○ 不能 O(1) 存取指定 index 的資料

● 這跟陣列不一樣的地方在哪?

(46)

加入資料

● 假設我們想將資料 C 插入在資料 A、B 之間

C

A B

(47)

加入資料

● 改變他們指向前後的那些箭頭!

C

A B

(48)

刪除資料

● 假設我們想將資料 B 從資料 A、C 之間刪除

A B C

(49)

例題討論

(50)

括弧匹配

給定一個僅包含 '('、')' 的字串,問其是否為合法括弧字串。

範例:

"()(()())" 是一個合法括弧字串

"()((()()" 不是一個合法括弧字串

(51)

括弧匹配

• 什麼樣的字串是合法括弧字串?

(52)

括弧匹配

• 什麼樣的字串是合法括弧字串?

• 「每個左括弧都能夠找到右括弧與其互相配對,且不會有多餘的右 括弧沒有配對到」

(53)

括弧匹配

• 由左到右把字元加到 stack 看看

• 遇到 '(' 就 push

• 遇到 ')' 就 pop

• 什麼樣的情況是非法字串?

(54)

括弧匹配

• 由左到右把字元加到 stack 看看

• 遇到 '(' 就 push

• 遇到 ')' 就 pop

• 什麼樣的情況是非法字串?

• 如果 pop 的時候發現 stack 空了 => 非法字串

• 如果 stack 最後不是空的 => 非法字串

(55)

長條圖最大矩形

給你一張長條圖每個位置的高度,問你能畫出的最大矩形面積。 (N

<= 10^5、高度 <= 10^9)

範例:

2 3 4 3 1

(56)

長條圖最大矩形

給你一張長條圖每個位置的高度,問你能畫出的最大矩形面積。 (N

<= 10^5、高度 <= 10^9)

範例:

2 3 4 3 1

(57)

長條圖最大矩形

• 不知道從何下手的時候,可以先從複雜度較差的解開始想!

(58)

直覺的做法

• 枚舉每段區間,然後看高度最高可以是多少

• 正確性?

• 複雜度?O(N^3)

• 區間總共有 N(N+1)/2 個

• 高度至多只能到最矮的那個 => 掃一遍區間找最小值

(59)

再想多一點...

• 「一塊區間的高度至多只能到最矮的那個」

(60)

再想多一點...

• 「一塊區間的高度至多只能到最矮的那個」

• 重點不是區間,是「最矮的那個」

• 從枚舉區間,變成枚舉每個 bar 的高度

(61)

再想多一點...

• 「一塊區間的高度至多只能到最矮的那個」

• 重點不是區間,是「最矮的那個」

• 從枚舉區間,變成枚舉每個 bar 的高度

• 如果我是最低的,那往左往右至多可以延伸多少?

• 只要分別找到左右兩邊第一個比我小的!

(62)

問題轉換

• 給定序列,對每一項分別找到左右離他最近且比他小的值。

(N <= 10^5、值域 <= 10^9 )

• 其實等價於對每一項找到左邊離他最近且比他小的值,然後再把序列 反轉過來做一次

• 複雜度?

• 但有沒有可能做得更好呢?

(63)

作法

• 考慮每一項在什麼時間點以後注定不可能成為答案

(64)

作法

• 考慮每一項在什麼時間點以後注定不可能成為答案

• 「如果右邊有東西不比我大,那我就不可能是答案」

• 我們要用 stack 維護這樣的「單調性」

stack 裡頭的每一項一定比前一項大

(65)

作法

• 考慮每一項在什麼時間點以後注定不可能成為答案

• 「如果右邊有東西不比我大,那我就不可能是答案」

• 我們要用 stack 維護這樣的「單調性」

stack 裡頭的每一項一定比前一項大

(66)

思路、步驟整理

1. 要找最大矩形,可以「枚舉每個值作為最小值」向外延伸 2. 將向左、向右拆開成兩個問題

3. 題目轉化為「找到左邊第一個比我小的值」

4. 一個值不可能成為最小值的條件(右邊出現比它小的值)

5. 利用 stack 維護這樣的「單調遞增」

(67)

謝謝大家!

參考文獻

相關文件

head data data NULL..

•  先定義一個struct/class Node,作為linked list的節點,裡面存資 訊和一個指向下一個Node的指標. • 

?: { machine learning, data structure, data mining, object oriented programming, artificial intelligence, compiler, architecture, chemistry, textbook, children book,. }. a

– File and index layers organize records on files, and manage the indexing data

大凡宗教都帶有救贖的功能,在傳佈過程中,小傳統社會的下層百姓,常

In the inverse boundary value problems of isotropic elasticity and complex conductivity, we derive estimates for the volume fraction of an inclusion whose physical parameters

Two examples of the randomly generated EoSs (dashed lines) and the machine learning outputs (solid lines) reconstructed from 15 data points.. size 100) and 1 (with the batch size 10)

• 如果把 queue 換成