Linked List

Jason @ Sprout C 2021 🌱

Linked List 是一種「資料結構」

顧名思義,就是一種儲存資料的結構

(´・ω・`)

已經學過的資料結構:陣列 Array

// Declaring an array with initial values
int array[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};

// Random Access
array[5] = array[7];

優點:宣告方便、Random Access

缺點:(*´・д・)?

Scenario I. Insertion at front

After

0

2

4

1

Before

0

2

4

在最前端插入 1

搬移 O(n)

+插入 O(1) 

時間複雜度  = 

Scenario II. Insertion when Full

After

0

2

4

1

Before

1

0

2

在最尾端插入 4

搬移 O(n)

+插入 O(1) 

時間複雜度  = 

開一個更大的新陣列

陣列 Array

優點

  1. 宣告方便
  2. Random Access

缺點

  1. 隨意位置插入複雜度最糟 O(n)
  2. 長度固定

偷渡一下大一面試資芽講師時做的梗圖 ε٩(๑> ₃ <)۶з 

解決方法?

換一種「適合的」資料結構!

這世界上還有很多種資料結構

 Linear

  • Array
  • Linked List
  • Queue
  • Stack
  • Deque
  • Dynamic Array

 Non-Linear

  • Graph
  • Hashtable
  • Tree
  • Trie
  • Bitset
  • Disjoint Set

 

  • Heap
  • Treap

😷  衛教宣導  😷

沒有「最好的」資料結構,

只有「最適合的」資料結構!

Linked List 想法

能不能夠當需要增加記憶體時就宣告一塊新的記憶體,

接著想辦法把它接到資料結構上就好了?

也許有一種資料結構能像火車一樣,

想加新車廂的時候就加一節新車廂進來就好?

Before

宣告一塊新的記憶體

After

接上去原本的資料結構

Revisit Scenario I. Insertion at Front

Before

宣告一塊新的記憶體

After

接上去原本的資料結構

Revisit Scenario II. Insertion when Full

解決 Array 遇到的問題了 !

但要怎麼用 C++ 來實作 Linked List 呢?

先從 Linked List 的最基本元件 Node 開始

每個 Node 都需要:

  1. 存自己的 Data
  2. 存下個 Node 的位置
  3. 把這些變數包起來
  4. 可以被動態宣告

pointer !

struct !

new / delete !

先從 Linked List 的最基本元件 Node 開始

struct node {
    int value;			// 要存的 Data
    node *next;			// 下個 Node 的指標

    node (int v) {		// 好用的建構子
        value = v;
        next = nullptr;
    }
};

所以只要有 Linked List 最前面那個 Node 

就能夠遍歷完整條 Linked List 了

現在給我們任何一個 Node,

我們都能夠找到它下一個 Node 的位置

// Iterate the whole Linked List
node *head;

void printList(node *n){
    while(n != nullptr){
    	cout << n->data << " ";
        n = n->next;
    }
}

Want proof ?  Mathematical Induction !

// Iterate the whole Linked List
node *head;

void printList(node *n){
    for( ; n != nullptr ; n = n->next)
    	cout << n->data << " ";
}

Insertion in Linked List

// Insert a new node after the given node

void insert(node *n, int v){
    node *new_node = new node(v);
    
    if (n->next != nullptr)
    	new_node->next = n->next;
    
    n->next = new_node;
}

Deletion in Linked List

// Delete the next node of the given node

void remove(node *n){
    if (n->next == nullptr)
    	return;
    
    node *next = n->next;
    n->next = next->next;
    delete next;
}

以上教的其實只是一種叫做 Singly Linked List 的 Linked List

還有一種叫做 Doubly Linked List 的 Linked List

不過基本上只是要維護的東西 (node *next, *pre) 變多了

其他地方都大同小異,所以留給大家自己想(?

Linked List  vs.  Array

Linked List Array
Accessing Sequential Random
Insertion O(1) O(n) in worst case
Space O(n) O(n)

想想看,我們能夠對 Linked List 做二分搜嗎?

如果時間剩太多的話

就直接直播解這兩題給大家看(?

上課練習題

Linked List

By jason-plainlog

Linked List

  • 664