[MasterThe Coding Interview]Linked List

本篇為MasterThe Coding Interview教學影片筆記文

從字面上的意思翻譯就是一種有連結的列表,列表中的每一個node都有兩項東西,一個是自己本身的值,另一個是pointer指向下一個node,以此方式串聯下去,最後一個node會指向null,表示後面沒有東西。LinkedList雖然表面上array很像,但他在最前面和最後面插入的時候,不用去移動整個陣列,時間複雜度會從原本array的O(n)變成O(1),其他部分的lookup、insert、delete都維持O(n)。

Implementing an Linked List

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
class Node{
constructor(v){
this.value = v;
this.next = null;
}
}

class LinkedList{
constructor(v){
this.head = {
value: v,
next: null
}
this.tail = this.head
this.length = 1;
}

append(v){
const newNode = new Node(v)
this.tail.next = newNode;
this.tail = newNode;
this.length++;
return this
}

prepend(v){
const newNode = new Node(v)
newNode.next = this.head
this.head = newNode
this.length++;
return this
}

printList(){
const array = [];
let currentNode = this.head;
while(currentNode !== null){
array.push(currentNode.value);
currentNode = currentNode.next;
}
return array;
}

insert(index , v){
if(index >= this.length){
return this.append(v);
}else if (index === 0) {
return this.prepend(v);
}

const newNode = new Node(v)
const leader = this.traversToIndex(index - 1);
const holdingPoter = leader.next;
leader.next = newNode;
newNode.next = holdingPoter;
this.length++;
return this;
}

remove(index){
if(index >= this.length){
const leader = this.traversToIndex(this.length - 2)
leader.next = null;
this.tail = leader;
this.length--;
return this
}
if(index == 0){
this.head = this.head.next;
this.length--;
return this
}

const leader = this.traversToIndex(index - 1)
const unwantedNode = leader.next
leader.next = unwantedNode.next
this.length--;
return this
}

traversToIndex(index){
let nowNode = this.head;
let counter = 0;
while(counter !== index){
nowNode = nowNode.next
counter++;
}
return nowNode
}
}

const myLinkedList = new LinkedList(10);
myLinkedList.append(5);
myLinkedList.append(16);
myLinkedList.prepend(1);
myLinkedList.insert(2 , 99);
myLinkedList.printList();

Doubly Linked Lists

一般來說linked list是單向的結構,我們只能從head開始到tail,但如果在每個node上都在多一個資料紀錄上一個node,那這個linked list就會變成雙向,從頭到尾或是從尾到頭都可以查找到所有node,以時間複雜度來說的話,doubly linked lists的查找可以比單向的節省1半的時間,因為可以同時從頭跟尾開始找,但bigO依舊還是O(n)。

Reverse Linked Lists

反轉單向鏈結串列是一個很常見的面試題,下面的程式碼銜接上面的linked list,是其中的一個方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
reverse(){
if(!this.head.next) return retrun this.head;

let first = this.head;
let second = first.next;

this.tail = this.head;

while(second){
const temp = second.next
second.next = first;
first = second;
second = temp;
}
this.head.next = null;
this.head = first;
return this;
}

When can use arry?

優點 缺點
Fast Insertion Slow lookups
Fast Deletion More Memory
Ordered
Flexible Size