Lunski's Clutter

This is a place to put my clutters, no matter you like it or not, welcome here.

0%

Linked List

串列結構

背景知識

OO, 基礎語法

理解問題

設計包含雜湊的串列結構,包含前中後插入,刪除,尋訪,反轉

思路視覺化

node(XYZ) <- node(ABC) <- None

Java

TC:
Add First: O(1), Last: O(n)
Insert: After: O(1)
Delete: O(n)

SC:
Add First: O(1), Last: O(n)
Insert: After: O(1)
Delete: O(1)

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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
import java.security.MessageDigest;

class LinkedList {
static class Node {
String data;
Node next;

Node(String d){
data = d;
next = null;
}
}

static Node head = null;
byte[] hash = null;

public static void addFirst(String data){
// make node
Node newNode = new Node(data);
// attach before head
newNode.next = head;
head = newNode;
System.out.print(newNode.data+"\n");

// hash
try {
MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
messageDigest.update(newNode.data.getBytes("UTF-8"));
String stringHash = new String(messageDigest.digest());
System.out.print("The hash is:"+stringHash+"\n");
} catch (Exception e) {
e.printStackTrace();
}
}

public static void addLast(String data){
// make node
Node newNode = new Node(data);
newNode.next = null;

// go to last, attach new node
if (head == null) {
head = newNode;
}else {
Node last = head;
while (last.next != null) {
last = last.next;
}
last.next = newNode;
}
System.out.print(newNode.data+"\n");

try {
MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
messageDigest.update(newNode.data.getBytes("UTF-8"));
String stringHash = new String(messageDigest.digest());
System.out.print("The hash is:"+stringHash+"\n");
} catch (Exception e) {
e.printStackTrace();
}
}

public static void insertAfter(Node prevNode, String data){
// build prevNode > newNode > newNode.next
Node newNode = new Node(data);
newNode.next = prevNode.next;
prevNode.next = newNode;
System.out.print(newNode.data+"\n");

try {
MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
messageDigest.update(newNode.data.getBytes("UTF-8"));
String stringHash = new String(messageDigest.digest());
System.out.print("The hash is:"+stringHash+"\n");
} catch (Exception e) {
e.printStackTrace();
}
}

public static void deleteNode(String key){
Node currNode = head, prev = null;

if (currNode != null && currNode.data.equals(key)) {
head = currNode.next;
System.out.println(key + " found and deleted");
}

while (currNode != null && !currNode.data.equals(key)) {
prev = currNode;
currNode = currNode.next;
}

if (currNode != null) {
prev.next = currNode.next;
System.out.println(key + " found and deleted \n");
}
if (currNode == null) {
System.out.println(key + " not found");
}
}

// 141. Linked List Cycle Floyd Algorithm return True/False
// O(N) Time, O(1) Space
public static Boolean detectCycle(Node head){
if(head == null || head.next == null) return false;

Node slow = head, fast = head;

while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;

if (slow == fast) return true;
}
return false;
}

// 142. Linked List Cycle II Floyd Algorithm return head
// O(N) Time, O(1) Space
public Node detectCycle2(Node head) {
Node slow = head, fast = head;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
// distance of slow and fast is half of cycle
if (slow == fast) break;
}

// fast hit end, no cycle
if (fast == null || fast.next == null) return null;

// start from head, Synchronize with slow, when head == slow, that is cycle start point
while (head != slow) {
head = head.next;
slow = slow.next;
}
return head;
}

public static void deletePosition(int index){
Node currNode = head, prev = null;

if (index == 0 && currNode != null) {
head = currNode.next; // Changed head
System.out.println(index + " position element deleted");
}

int counter = 0;
while (currNode != null) {
if (counter == index) {
prev.next = currNode.next;

System.out.println(index + " position element deleted");
break;
} else {
prev = currNode;
currNode = currNode.next;
counter++;
}
}

if (currNode == null) {
System.out.println(index + " position element not found");
}
}

public static void reverse(){
Node cur = head, prev = null, next = null;

while (cur != null) {
next = cur.next;
cur.next = prev;

// shift to next node
prev = cur;
cur = next;
}

head = prev;
}

public static Node reverseRec(Node head, Node newHead){
if (head == null) return newHead;
Node next = head.next;
head.next = newHead;
return reverseRec(next, head); // head > next; newHead > head
}

public static void printList(){
Node currNode = head;

while (currNode != null) {
System.out.print(currNode.data + " ");
currNode = currNode.next;
}
System.out.println("\n");
}
// overloaded
public static void printList(Node node) {
while (node != null) {
System.out.print(String.valueOf(node.data) + " ");
node = node.next;
}
}

public static void main(String[] args){
LinkedList list = new LinkedList();

list.addFirst("A");
list.addFirst("B");
list.addFirst("C");
list.insertAfter(list.head.next, "000");
list.addLast("Z");

System.out.println("Given Linked List");
list.printList();

System.out.println("Loop? "+ list.detectCycle(list.head));

// https://web.ntnu.edu.tw/~algo/Function.html#4
System.out.println("Loop point? "+ list.detectCycle2(list.head));

System.out.println("Delete node B");
list.deleteNode("B");
list.printList();

System.out.println("Delete position 1");
list.deletePosition(1);
list.printList();

System.out.println("Reversed Linked List");
list.reverse();
list.printList();

System.out.println("Rec Reversed Linked List");
Node node = reverseRec(list.head, null);
printList(node);
}
}

>
java -cp /tmp/58myPYH7S0 LinkedList
A
The hash is:U????d?y]9 q?????r?O?U????????
B
The hash is:?~p?D??K??J?7???K?p?b??m?2
\
C
The hash is:k#???]??????5]?'}?? 9?e[??

000
The hash is:*??tj?T:???????:???o?3?)G"(U?
Z
The hash is:??????iTm??y??P_*!Y????kN???
Given Linked List /n
C B 000 A Z

Loop? false

Loop point? null

Delete node B
B found and deleted

C 000 A Z

Delete position 1
1 position element deleted
C A Z

Reversed Linked List
Z A C

Rec Reversed Linked List
C A Z

Python

TC:
Add First: O(1), Last: O(n)
Insert: After: O(1)
Delete: O(n)

SC:
Add First: O(1), Last: O(n)
Insert: After: O(1)
Delete: O(1)

  • 基礎結構
1
2
3
4
5
6
7
8
9
10
class Node:
def __init__(self, data):
self.data = data
self.next = None

class LinkedList:
# Function to initialize head
def __init__(self):
self.head = None
self.hash = None
  • 新增
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
def add_first(self, new_data):
# 1. make node
if not isinstance(new_data, Node):
new_node = Node(new_data)
# 2. node point to list head
new_node.next = self.head
# 3. head move to new head
self.head = new_node
# 4. hash
# self.hash = hash(new_node) # same object, same hash result

print(new_node.data)
hash_ = hash((new_node.data, new_node.next))
print('The hash is:', end = '')
print(hash_)
new_node.hash = hash_

def add_last(self, new_data):
# 1. make node
if not isinstance(new_data, Node):
new_node = Node(new_data)

# 2. Linked List is empty, new node as head
if self.head is None:
self.head = new_node
return

# 3. Traverse till the last node
last = self.head
while (last.next):
last = last.next
# 4. Change the next of last node
last.next = new_node

print(new_node.data)
hash_ = hash((new_node.data, new_node.next))
print('The hash is:', end = '')
print(hash_)
new_node.hash = hash_
  • 插入
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
def insert_after(self, prev_node, new_data):
if prev_node is None:
print("The given previous node must inLinkedList.")
return

# 1. make node
if not isinstance(new_data, Node):
new_node = Node(new_data)
# 2. point to old node pointed to
new_node.next = prev_node.next
# 3. prev point to this node
prev_node.next = new_node

print(new_node.data)
hash_ = hash((new_node.data, new_node.next))
print('The hash is:', end = '')
print(hash_)
new_node.hash = hash_
  • 刪除
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
def deleteNode(self, key):
# 1. store head
temp = self.head

if temp == None: return

# 2. key is in head
if temp is not None and temp.data == key:
self.head = temp.next
temp = None
return

# 3. Search for the key to be deleted,
while temp is not None:
if temp.data == key:
break
prev = temp
temp = temp.next

# 4. Unlink tne node
prev.next = temp.next
temp = None
  • 反轉, 遞迴,非遞迴
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
def reverse(self):
# Two pointer, current, prev
cur = self.head
prev = None

# prev > cur > next >> prev < cur < next
while cur is not None:
next = cur.next # store next node
cur.next = prev # change next node to previous

# shift to next node
prev = cur
cur = next

self.head = prev # reset head

def reverseRec(self, head):
# If head is empty or has reached the list end
if head is None or head.next is None:
return head

# Reverse the rest list
newHead = self.reverseRec(head.next)

# Put first element at the end
head.next.next = head
head.next = None

# Fix the header pointer
return newHead
  • 顯示
1
2
3
4
5
6
7
# Utility function to print the linked LinkedList
def printList(self): # __iter__(self):
temp = self.head

while(temp):
print(temp.data, end = " ") # yield node
temp = temp.next
  • main
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
if __name__=='__main__':
llist = LinkedList()
llist.add_first("A")
llist.add_first("B")
llist.add_first("C")
llist.insert_after(llist.head.next, "000")
llist.add_last("Z")

print()
print("Given Linked List")
llist.printList()

print()
print("Delete node B")
llist.deleteNode("B")
llist.printList()

print("\nReversed Linked List")
llist.reverse()
llist.printList()

llist.head = llist.reverseRec(llist.head)
print("\nRec Reversed Linked List")
llist.printList()

>
A
The hash is:-6923208582321617352
B
The hash is:8939411171582669658
C
The hash is:364725502475584520
000
The hash is:-6125763954762708938
Z
The hash is:647066987114918698

Given Linked List
C B 000 A Z
Delete node B
C 000 A Z
Reversed Linked List
Z A 000 C
Rec Reversed Linked List
C 000 A Z

ref


如果你覺得這篇文章很棒,請你不吝點讚 (゚∀゚)

Welcome to my other publishing channels