Linked Lists

27
LINKED LISTS Prof. Michael Tsai 2012/3/13 作作 作作 5pm 作作 作作作作作 2:20pm 作作 作作作作作作作 作作作作作

description

Linked Lists. Prof. Michael Tsai 2012/3/13. 作業一今天 5pm 到期 下次作業 起 2:20pm 到期. 作業二今晚公布 兩周 後到期. 大家來吐 Array 的槽. Array 有什麼不好 ? 插入新 element 刪除原本的 element Time complexity= O(??). Array 的複雜度. 新朋友 : Linked List. 要怎麼讓資料 1. 可以隨便亂排 2. 但是我們仍然知道他的順序 ? 答案 : 資料亂 排 但是 , 另外存 “ 下一個是誰 ”. index. - PowerPoint PPT Presentation

Transcript of Linked Lists

Page 1: Linked Lists

LINKED LISTSProf. Michael Tsai2012/3/13 作業一今天 5pm 到期下次作業起 2:20pm 到期

作業二今晚公布兩周後到期

Page 2: Linked Lists

2

大家來吐 Array 的槽• Array 有什麼不好 ?• 插入新 element

• 刪除原本的 element

• Time complexity= O(??)

1 3 4 2 5 空1 3 新的 4 2 5

1 3 4 2 51 3 2 5

Page 3: Linked Lists

3

Array 的複雜度Array Dynamic Array

(滿了以後擴充成兩倍 )

Linked List (今天要學的 )

Indexing ( 拿某一個元素 )

O(1) O(1) ??

在開頭 Insert/Delete

O(n), only feasible if not full

O(n) ??

在尾巴 Insert/Delete

O(1), only feasible if not full

O(1), if not fullO(n), if full

??

在中間 Insert/Delete

O(n), only feasible if not full

O(n) ??

浪費的空間 0 O(n) ??

Page 4: Linked Lists

4

新朋友 : Linked List• 要怎麼讓資料• 1. 可以隨便亂排• 2. 但是我們仍然知道他的順序 ?

• 答案 :• 資料亂排• 但是 , 另外存“下一個是誰”

若漢 維楨 冠綸 主恩 步青4 0 1 -1 3

資料

開始 1

下一個是誰

index [0] [1] [2] [3] [4]

Page 5: Linked Lists

5

概念上 , 應該是長這樣

若漢 維楨 冠綸 主恩 步青4 0 1 -1 3

資料

開始 2

下一個是誰

index [0] [1] [2] [3] [4]

若漢維楨冠綸 主恩 Null步青

真正的樣子 :

開始

Page 6: Linked Lists

6

增加一個人 ?

佩璇

若漢 維楨 冠綸 主恩 步青 佩璇4 0 1 -1 3

資料

開始 2

下一個是誰

index [0] [1] [2] [3] [4] [5]

4 0 1 -1 3 04 5 1 -1 3 0

若漢維楨冠綸 主恩 Null步青開始

Page 7: Linked Lists

7

刪掉一個人

若漢 維楨 冠綸 主恩 步青 佩璇資料

開始 2

下一個是誰

index [0] [1] [2] [3] [4] [5]

4 5 1 -1 3 04 5 1 -1 3 4

佩璇

若漢維楨冠綸 主恩 Null步青開始

Page 8: Linked Lists

8來看一些 code ( 用 malloc/free)• 怎麼宣告一個 node 的 struct?struct ListNode {int data;struct ListNode *next;

};

• 怎麼拿一個新的 node?• struct ListNode *new;• new=(struct ListNode*)malloc(sizeof(struct listNode));

Page 9: Linked Lists

9

來看一些 code• new 是指標 , 指到一個 struct listNode 的變數 .• 那如果要拿這個變數裡面的 data 呢 ?• 可以這樣寫 :• (*new).data• 或者 , • new->data

• 要拿 next 呢 ?• (*new).next• 或者 ,• new->next

Page 10: Linked Lists

10

來看一些 code• 假設 head 指到第一個 struct ListNode

• 那麼我要拿到 551 的下一個 ListNode 的位址怎麼寫 ?• head->link->link ( 連續技 )

551342

head

Page 11: Linked Lists

11

製造兩個 nodestruct ListNode *head, *tmp;

tmp=(struct ListNode*)malloc(sizeof(struct ListNode)); if (tmp==NULL)

exit(-1); // exit program on errortmp->data=551;tmp->next=NULL;head=tmp;tmp=(struct ListNode*)malloc(sizeof(struct ListNode));tmp->data=342;tmp->next=head;head=tmp;

551342

head

Page 12: Linked Lists

12

插入一個新 node 在某 node 後面• struct ListNode *x; // 指到要插入的 node 的位置• struct ListNode *new;

• new=(struct ListNode*)malloc(sizeof(struct ListNode));• new->data=123;

• 下一步呢 ? 先處理 new->next 還是 x->next?• new->next=x->next;• x->next=new;

551342

x

342

123

new

Page 13: Linked Lists

13

刪除某一個 node• struct ListNode *head; // 指到一開始的 node 的位置• struct ListNode *x; // 指到要刪除的 node 的位置• struct ListNode *trail; // 指到 x 的前一個 node 的位置• 分兩種狀況處理 : x 是頭 , 還有 x 不是頭if (trail) //x 不是第一個 node

trail->next=x->next;else

head=x->next;free(x);

551342

x

342

trail

551

342

xhead

Page 14: Linked Lists

14

Examples• 印出整個 linked liststruct ListNode *tmp;for(tmp=head; tmp!=NULL; tmp=tmp->next)

printf(“%d “, tmp->data);

• 找到某個 node有 data的前一個 node的位置int a=123; //假設我們要找資料是 123的 node的前一個 node位置struct ListNode *tmp;for(tmp=head; tmp!=NULL; tmp=tmp->next) {

if (tmp->next!=NULL) { // 因為 tmp->next可能是 NULL!if (tmp->next->data==a)

break; // break出去的時候 , tmp就是我們要的}

}

Page 15: Linked Lists

15

Array和 Linked List的複雜度比較Array Dynamic Array

(滿了以後擴充成兩倍 )

Linked List

Indexing ( 拿某一個元素 )

O(1) O(1) O(n)

在開頭 Insert/Delete

O(n), only feasible if not full

O(n) O(1)

在尾巴 Insert/Delete

O(1), only feasible if not full

O(1), if not fullO(n), if full

O(n) 找到尾巴O(1) insert/delete

在中間 Insert/Delete

O(n), only feasible if not full

O(n) O(n) 找到位置O(1) insert/delete

浪費的空間( 不是拿來存資料的部分 )

0 ( 存滿以後 ) O(n)( 最多可能有一半的空間是空的 )

O(n)( 每個 node 都有拿來存 next node 的位址欄位 )

Page 16: Linked Lists

16

< 動腦時間 >• 有沒有什麼是 array 比 linked list 好的 ?

• 什麼時候用 array?

• 什麼時候用 linked list?

• < 練習題 1> 我想要找 linked list 裡面從尾巴數過來的第k 個 node, 要怎麼寫 code? 時間複雜度為 ?

練習題1答案: O(n), Karumanchi 3.10 problem 2,4,5

Page 17: Linked Lists

17

Example: Stacks & Queues• 如果是一塊記憶體要放很多 stack 或 queue• 就很難做到很 efficient• 例如如果某一 stack 滿了 , 就要把一堆資料往後擠• 就不是 O(1) 了 T_T

• 解決 : 跟 Linked List 當朋友

Page 18: Linked Lists

18

Stack• 要怎麼拿來當 stack 呢 ? ( 想想怎麼做主要的 operation)• push & pop• 請一位同學來講解

• 例 : push(“ 子華” )• start 當作 stack top• 怎麼寫 code? (hw2 problem 2)• 那 pop 呢 ?

主恩若漢子華 政皓 Null孟桓

head

Page 19: Linked Lists

19

Queue• 類似 stack 的作法• 不過頭尾都要有一個指標• 從頭拿 , 從尾放

• 怎麼拿 ? (DeQueue)struct ListNode* tmp;tmp=front;front=front->link;tmp_data=tmp->data;free(tmp);return tmp_data;

若漢子華 主恩 Null政皓front

rear

Page 20: Linked Lists

20

Queue

• 那怎麼放 ?• 假設 new 是指到新的 node• rear->next=new;• new->next=NULL;• rear=new;

若漢子華 主恩政皓front rear

new

立群

Page 21: Linked Lists

21練習題 2: 把 linked list 反過來• 反過來 : 把

• 變成

• 怎麼弄 ?

3 14 2 8 1 0a

1 0 2 8 3 14b

答案: Karumanchi 3.10 problem 16

Page 22: Linked Lists

22

Singly v.s. doubly linked list

• 什麼時候需要用雙 ?• Singly linked list 只能往後 , 不能往前 ( 要從最前面開始重新找 )• Doubly linked list 用在常常需要”倒帶”的時候• 好處 :

• 倒帶方便 (O(1)) ( 想想在 singly linked list 裡面要刪掉一個 node 時 , 必須要找到前一個 node)

• 壞處 :• 兩個 pointer 的儲存空間 • Insert/delete 的時候稍微慢一點 ( 要處理兩個 pointer, next & prev)

3 14 2 8 1 0head

Singly linked list:

3 14

2 8 1 0head

Doubly linked list:

Page 23: Linked Lists

23

回收很慢• 要把一個用完的 linked list 每個 node 都 free 掉 (Why?)

• 有幾項就要幾項的時間 : O(n)

• 懶人方法 : 丟到一個”回收桶” , 之後需要的時候再撿出來• 希望丟 =O(1), 而且撿 =O(1)

• 怎麼做 ?

• 關鍵 : 找尾巴很慢 . ( 不是 O(1))• 但是又不想多花空間紀錄尾巴

3 14a 2 8 1 0

回收桶

Page 24: Linked Lists

24

Circular List• “ 開始”的那個箭頭 , 指在尾巴• 最後一個 node 指回開頭• 有什麼好處 ? 串接很方便 !• 丟進回收桶 =O(1) !!

• 也可以有 doubly circular linked list!

3 14

head

2 8 1 0

回收桶temp

Page 25: Linked Lists

25

暫停 !• 來回想一下我們學了哪些種類的 linked list

• Singly linked list• Circular• Non-circular (chain)

• Doubly linked list• Circular• Non-circular (chain)

Page 26: Linked Lists

26

Today’s Reading Assignments

• Karumanchi 3.1-3.8• 有很多的 source code, 特別是 3.6 的部分是基礎 , 一定要看懂 !

• Karumanchi 3.10 problem {2,4,5},{15,16},{24,25,27}

Page 27: Linked Lists

27

上課前要講的事項• Bravo for 資訊之夜 !

• HW2 Bonus (5%):• Please write down your constructive suggestion for the

course based on the lectures and homework so far; what are the things that you would like us to change and how?

• 建議 :• 上課不要開筆記型電腦• 印一份講義帶來上課 , 用鉛筆作筆記 ( 有時候可以練習題目 )• 這樣比較不容易睡著+參與度會比較高喔• 老師會盡量背你們的名字