-
Notifications
You must be signed in to change notification settings - Fork 0
/
Single-Linked-List.py
389 lines (328 loc) · 12.3 KB
/
Single-Linked-List.py
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
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
# Creating a Node : Data + address of next node
class Node:
def __init__(self,data):
self.data = data
self.next = None
# This class will create a linked list
# and initialize it with a head = None
# It also contain all functions to perform
class LinkedList:
# constructor to initialize linked list with a head
def __init__(self):
self.head = None
# insert function will add new node at last
def insert(self,new_data):
if self.head == None:
self.head = Node(new_data)
else:
temp = self.head
while temp.next != None:
temp = temp.next
temp.next = Node(new_data)
# This function will add new node right after the node whose value is given by user
def insertAfter(self,data,new_data):
# checking if linked list is empty
if self.head == None:
print("\nThere is no existing data. First insert some value!\n")
else:
temp = self.head
while temp != None and temp.data != data:
temp = temp.next
# check if temp is at None
if temp == None:
print(data,"doesn't exist !\n")
else:
# Now temp is pointing the node next to which insertion takes place
new_node = Node(new_data)
new_node.next = temp.next
temp.next = new_node
# This function delete that node whose value is given by user
def deleteByValue(self,data):
# checking if linked list is empty
if self.head == None:
print("\nCan't delete, Linked List is Empty !\n")
else:
# if the node to be deleted is head
if self.head.data == data:
del_node = self.head
self.head = self.head.next
print("\n",del_node.data,"deleted successfully !\n")
del del_node
else:
temp = self.head
while temp.next != None and temp.next.data != data:
temp = temp.next
# temp is at last node, and the node to be deleted is not yet found
if temp.next == None:
print(data,"doesn't exist !\n")
else:
# Here temp will point to the node which is just before the node
# to be deleted
del_node = temp.next
temp.next = del_node.next
print("\n",del_node.data,"deleted successfully !\n")
del del_node
# This function deletes node based on its index(0,1,2,3,...)
def deleteByIndex(self,idx):
# checking if linked list is empty
if self.head == None:
print("\nCan't delete, Linked List is Empty !\n")
# if the node to be deleted is head
else:
if idx == 0:
del_node = self.head
self.head = self.head.next
print("\nIndex :",idx,"Value :",del_node.data,"deleted successfully!\n")
del del_node
else:
temp = self.head
for i in range(idx-1):
if temp != None:
temp = temp.next
if temp == None or idx<0:
print("\nGiven index is out of range!\n")
else:
# temp is previous to the node to be deleted
del_node = temp.next
temp.next = del_node.next
print("\nIndex :",idx,"Value :",del_node.data,"deleted successfully!\n")
del del_node
# This function return total number of elements in Linked List
def length(self):
if self.head == None:
return 0
else:
count = 0
temp = self.head
while temp!=None:
temp = temp.next
count += 1
return count
# This function deletes alternate nodes like node 2,4,6,...
def delAlternateNodes(self):
# checking if linked list is empty
if self.head == None:
print("\nCan't delete, Linked List is Empty !\n")
elif self.length() == 1:
print("\nCan't delete, Only 1 element!\n")
else:
first = self.head # 1st node
second = self.head.next # 2nd node
while first != None and second != None:
first.next = second.next
del second
first = first.next
if first != None:
second = first.next
# This function linearly searches the key given by user
######Iterative Approach######
def LinearSearch(self,key):
# checking if linked list is empty
if self.head == None:
print("\nLinked List is empty!\n")
return -1
else:
temp = self.head
while temp != None:
if temp.data == key:
return 1
temp = temp.next
return -1
######Recursive Approach######
# def LinearSearch(self,start,key):
# # checking if linked list is empty
# if start == None:
# return -1
# else:
# if start.data == key:
# return 1
# return self.LinearSearch(start.next,key)
# This is helper function for BinarySearch()
# It returns middle node of Linked List
def middle(self,start,last):
if start == None:
return None
slow = start
fast = start
while fast != last and fast.next != last:
slow = slow.next
fast = fast.next.next
return slow
# This function sear5ches the key given by user by binary approach
def BinarySearch(self,start,last,key):
if start != None and start != last:
mid = self.middle(start,last)
if mid == None:
return -1
elif mid.data == key:
return 1
elif mid.data > key:
return self.BinarySearch(start,mid,key)
elif mid.data < key:
return self.BinarySearch(mid.next,last,key)
return -1
# This function sorts the linked list based on data
def BubbleSort(self):
# checking if linked list is empty
if self.head == None:
print("\nLinked List is empty!\n")
else:
temp1 = self.head
while temp1 != None:
temp2 = self.head
while temp2.next != None:
if temp2.data > temp2.next.data:
# swapping
temp2.data, temp2.next.data = temp2.next.data, temp2.data
temp2 = temp2.next
temp1 = temp1.next
# This function sorts the linked list based on data
def SelectionSort(self):
# checking if linked list is empty
if self.head == None:
print("\nLinked List is empty!\n")
else:
temp1 = self.head
while temp1 != None:
min_node = temp1
temp2 = temp1.next
while temp2!= None:
if min_node.data > temp2.data:
min_node = temp2
temp2 = temp2.next
# swapping
temp1.data, min_node.data = min_node.data, temp1.data
temp1 = temp1.next
# This function displays the frequency of every elements
def FrequencyOfElements(self):
# checking if linked list is empty
if self.head == None:
print("\nLinked List is empty!\n")
else:
d = {}
temp1 = self.head
while temp1 != None:
if temp1.data in d:
d[temp1.data] += 1
else:
d[temp1.data] = 1
temp1 = temp1.next
print(d)
# This function checks if there is loop in Linked List
def checkLoop(self):
########Floyd’s Cycle-Finding Algorithm#########
'''Traverse linked list using two pointers.Move one pointer
slow by one and another pointer fast by two. If they become
equal then loop exists'''
slow = self.head
fast = self.head
while slow != None and fast != None and fast.next != None:
slow = slow.next
fast = fast.next.next
if slow == fast:
return True
return False
# This function reverses the Linked List
def reverse_list(self) :
if self.head == None or self.head.next == None:
return
pre = None
curr = self.head
nex = curr.next
while curr != None:
curr.next = pre
pre = curr
curr = nex
if nex != None:
nex = nex.next
self.head = pre
def removeDuplicates(self):
if self.head == None:
return head
else:
temp = self.head
while temp.next != None:
if temp.data == temp.next.data:
temp.next = temp.next.next
else:
temp = temp.next
# This function prints all elements of Linked List
def display(self):
if self.head == None:
print("\nLinked List is empty !\n")
else:
temp = self.head
while temp != None:
print(temp.data, end = " -> ")
temp = temp.next
print("None")
# driver code
my_list = LinkedList()
while True:
print("\n1. Insert \n2. Delete \n3. Display \n4. Length of Linked List \n5. Searching \
\n6. Sorting \n7. Extra Functions \n8. Exit \n")
choice = int(input("Enter your choice : "))
if choice == 1:
data = int(input("\nEnter data to insert : "))
a = int(input("1. Insert in last \n2. Insert after a value \n"))
if a == 1:
my_list.insert(data)
print("\nInserted Successfully!\n")
elif a == 2:
temp = int(input("Enter value after which given value is inserted : "))
my_list.insertAfter(temp,data)
print("\nInserted Successfully!\n")
elif choice == 2:
a = int(input("1. Delete by value \n2. Delete by index \n3. Delete Alternate Nodes \n"))
if a == 1:
data = int(input("\nEnter data to delete : "))
my_list.deleteByValue(data)
elif a == 2:
idx = int(input("\nEnter index to delete : "))
my_list.deleteByIndex(idx)
elif a == 3:
my_list.delAlternateNodes()
print("\nAlternate Nodes deleted successfully\n")
elif choice == 3:
my_list.display()
elif choice == 4:
print("\nTotal elements in Linked List = ",my_list.length())
elif choice == 5:
data = int(input("\nEnter element to find : "))
a = int(input("\n1. Linear Search \n2. Binary Search \n"))
if a == 1:
result = my_list.LinearSearch(data)
elif a ==2:
result = my_list.BinarySearch(my_list.head,None,data)
if result == -1:
print(data,"not found!\n")
else:
print(data,"found!\n")
elif choice == 6:
a = int(input("1. Bubble Sort \n2. Selection Sort \n"))
if a == 1:
my_list.BubbleSort()
elif a == 2:
my_list.SelectionSort()
print("\nSorted Array is : ")
my_list.display()
elif choice == 7:
a = int(input("\n1. Frequency of Elements \n2. Reverse Linked List \n3. Detect Loop \n4. Remove Duplicate Elements from Sorted Linked List \n"))
if a == 1:
my_list.FrequencyOfElements()
elif a == 2:
my_list.reverse_list()
print("\nReversed Linked List : - ")
my_list.display()
elif a == 3:
loop = my_list.checkLoop()
if loop == True:
print("\nLoop exists!\n")
else:
print("\nLoop doesn't exists!\n")
elif a == 4:
my_list.removeDuplicates()
elif choice == 8:
break
else:
print("\nWrong Choice !\n")