Skip to content

Commit 6ecc058

Browse files
Merge pull request #2517 from Mugendesu/master
All LinkedList types
2 parents d816730 + 389d60d commit 6ecc058

File tree

3 files changed

+612
-0
lines changed

3 files changed

+612
-0
lines changed
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
'''Author - Mugen https://github.com/Mugendesu'''
2+
3+
class Node :
4+
def __init__(self , data , next = None):
5+
self.data = data
6+
self.next = next
7+
8+
class CircularLinkedList :
9+
def __init__(self):
10+
self.head = self.tail = None
11+
self.length = 0
12+
13+
def insert_at_beginning(self , data):
14+
node = Node(data , self.head)
15+
if self.head is None:
16+
self.head = self.tail = node
17+
node.next = node
18+
self.length += 1
19+
return
20+
self.head = node
21+
self.tail.next = node
22+
self.length += 1
23+
24+
def insert_at_end(self , data):
25+
node = Node(data , self.head)
26+
if self.head is None:
27+
self.head = self.tail = node
28+
node.next = node
29+
self.length += 1
30+
return
31+
self.tail.next = node
32+
self.tail = node
33+
self.length += 1
34+
35+
def len(self):
36+
return self.length
37+
38+
def pop_at_beginning(self):
39+
if self.head is None:
40+
print('List is Empty!')
41+
return
42+
self.head = self.head.next
43+
self.tail.next = self.head
44+
self.length -= 1
45+
46+
def pop_at_end(self):
47+
if self.head is None:
48+
print('List is Empty!')
49+
return
50+
temp = self.head
51+
while temp:
52+
if temp.next is self.tail:
53+
self.tail.next = None
54+
self.tail = temp
55+
temp.next = self.head
56+
self.length -= 1
57+
return
58+
temp = temp.next
59+
60+
def insert_values(self , arr : list):
61+
self.head = self.tail = None
62+
self.length = 0
63+
for i in arr:
64+
self.insert_at_end(i)
65+
66+
def print(self):
67+
if self.head is None:
68+
print('The List is Empty!')
69+
return
70+
temp = self.head.next
71+
print(f'{self.head.data} ->' , end=' ')
72+
while temp != self.head:
73+
print(f'{temp.data} ->' , end=' ')
74+
temp = temp.next
75+
print(f'{self.tail.next.data}')
76+
77+
def insert_at(self , idx , data):
78+
if idx == 0:
79+
self.insert_at_beginning(data)
80+
return
81+
elif idx == self.length:
82+
self.insert_at_end(data)
83+
return
84+
elif 0 > idx or idx > self.length:
85+
raise Exception('Invalid Position')
86+
return
87+
pos = 0
88+
temp = self.head
89+
while temp:
90+
if pos == idx - 1:
91+
node = Node(data , temp.next)
92+
temp.next = node
93+
self.length += 1
94+
return
95+
pos += 1
96+
temp = temp.next
97+
98+
def remove_at(self , idx):
99+
if 0 > idx or idx >= self.length:
100+
raise Exception('Invalid Position')
101+
elif idx == 0:
102+
self.pop_at_beginning()
103+
return
104+
elif idx == self.length - 1:
105+
self.pop_at_end()
106+
return
107+
temp = self.head
108+
pos = 0
109+
while temp:
110+
if pos == idx - 1:
111+
temp.next = temp.next.next
112+
self.length -= 1
113+
return
114+
pos += 1
115+
temp = temp.next
116+
117+
def main():
118+
ll = CircularLinkedList()
119+
ll.insert_at_end(1)
120+
ll.insert_at_end(4)
121+
ll.insert_at_end(3)
122+
ll.insert_at_beginning(2)
123+
ll.insert_values([1 , 2, 3 ,4 ,5 ,6,53,3])
124+
# ll.pop_at_end()
125+
ll.insert_at(8, 7)
126+
# ll.remove_at(2)
127+
ll.print()
128+
print(f'{ll.len() = }')
129+
130+
131+
132+
if __name__ == '__main__':
133+
main()
Lines changed: 245 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,245 @@
1+
'''Contains Most of the Doubly Linked List functions.\n
2+
'variable_name' = doubly_linked_list.DoublyLinkedList() to use this an external module.\n
3+
'variable_name'.insert_front('element') \t,'variable_name'.insert_back('element'),\n
4+
'variable_name'.pop_front() are some of its functions.\n
5+
To print all of its Functions use print('variable_name'.__dir__()).\n
6+
Note:- 'variable_name' = doubly_linked_list.DoublyLinkedList() This line is Important before using any of the function.
7+
8+
Author :- Mugen https://github.com/Mugendesu
9+
'''
10+
class Node:
11+
def __init__(self, val=None , next = None , prev = None):
12+
self.data = val
13+
self.next = next
14+
self.prev = prev
15+
16+
class DoublyLinkedList:
17+
18+
def __init__(self):
19+
self.head = self.tail = None
20+
self.length = 0
21+
22+
def insert_front(self , data):
23+
node = Node(data , self.head)
24+
if self.head == None:
25+
self.tail = node
26+
node.prev = self.head
27+
self.head = node
28+
self.length += 1
29+
30+
def insert_back(self , data):
31+
node = Node(data ,None, self.tail)
32+
if self.head == None:
33+
self.tail = self.head = node
34+
self.length += 1
35+
else:
36+
self.tail.next = node
37+
self.tail = node
38+
self.length += 1
39+
40+
def insert_values(self , data_values : list):
41+
self.head = self.tail = None
42+
self.length = 0
43+
for data in data_values:
44+
self.insert_back(data)
45+
46+
def pop_front(self):
47+
if not self.head:
48+
print('List is Empty!')
49+
return
50+
51+
self.head = self.head.next
52+
self.head.prev = None
53+
self.length -= 1
54+
55+
def pop_back(self):
56+
if not self.head:
57+
print('List is Empty!')
58+
return
59+
60+
temp = self.tail
61+
self.tail = temp.prev
62+
temp.prev = self.tail.next = None
63+
self.length -= 1
64+
65+
def print(self):
66+
if self.head is None:
67+
print('Linked List is Empty!')
68+
return
69+
70+
temp = self.head
71+
print('NULL <-' , end=' ')
72+
while temp:
73+
if temp.next == None:
74+
print(f'{temp.data} ->' , end = ' ')
75+
break
76+
print(f'{temp.data} <=>' , end = ' ')
77+
temp = temp.next
78+
print('NULL')
79+
80+
def len(self):
81+
return self.length # O(1) length calculation
82+
# if self.head is None:
83+
# return 0
84+
# count = 0
85+
# temp = self.head
86+
# while temp:
87+
# count += 1
88+
# temp = temp.next
89+
# return count
90+
91+
def remove_at(self , idx):
92+
if idx < 0 or self.len() <= idx:
93+
raise Exception('Invalid Position')
94+
if idx == 0:
95+
self.pop_front()
96+
return
97+
elif idx == self.length -1:
98+
self.pop_back()
99+
return
100+
temp = self.head
101+
dist = 0
102+
while dist != idx-1:
103+
dist += 1
104+
temp = temp.next
105+
temp.next = temp.next.next
106+
temp.next.prev = temp.next.prev.prev
107+
self.length -= 1
108+
109+
def insert_at(self , idx : int , data ):
110+
if idx < 0 or self.len() < idx:
111+
raise Exception('Invalid Position')
112+
if idx == 0:
113+
self.insert_front(data)
114+
return
115+
elif idx == self.length:
116+
self.insert_back(data)
117+
return
118+
temp = self.head
119+
dist = 0
120+
while dist != idx-1:
121+
dist += 1
122+
temp = temp.next
123+
node = Node(data , temp.next , temp)
124+
temp.next = node
125+
self.length += 1
126+
127+
def insert_after_value(self , idx_data , data):
128+
if not self.head : # For Empty List case
129+
print('List is Empty!')
130+
return
131+
132+
if self.head.data == idx_data: # To insert after the Head Element
133+
self.insert_at(1 , data)
134+
return
135+
temp = self.head
136+
while temp:
137+
if temp.data == idx_data:
138+
node = Node(data , temp.next , temp)
139+
temp.next = node
140+
self.length += 1
141+
return
142+
temp = temp.next
143+
print('The Element is not in the List!')
144+
145+
def remove_by_value(self , idx_data):
146+
temp = self.head
147+
if temp.data == idx_data:
148+
self.pop_front()
149+
return
150+
elif self.tail.data == idx_data:
151+
self.pop_back()
152+
return
153+
while temp:
154+
if temp.data == idx_data:
155+
temp.prev.next = temp.next
156+
temp.next.prev = temp.prev
157+
self.length -= 1
158+
return
159+
if temp != None:
160+
temp = temp.next
161+
print("The Element is not the List!")
162+
163+
def index(self , data):
164+
'''Returns the index of the Element'''
165+
if not self.head :
166+
print('List is Empty!')
167+
return
168+
idx = 0
169+
temp = self.head
170+
while temp:
171+
if temp.data == data: return idx
172+
temp = temp.next
173+
idx += 1
174+
print('The Element is not in the List!')
175+
176+
def search(self , idx):
177+
'''Returns the Element at the Given Index'''
178+
if self.len() == 0 or idx >= self.len():
179+
raise Exception('Invalid Position')
180+
return
181+
temp = self.head
182+
curr_idx = 0
183+
while temp:
184+
if curr_idx == idx:
185+
return temp.data
186+
temp = temp.next
187+
curr_idx += 1
188+
189+
def reverse(self):
190+
if not self.head:
191+
print('The List is Empty!')
192+
return
193+
prev = c_next = None
194+
curr = self.head
195+
while curr != None:
196+
c_next = curr.next
197+
curr.next = prev
198+
prev = curr
199+
curr = c_next
200+
self.tail = self.head
201+
self.head = prev
202+
203+
def mid_element(self):
204+
if not self.head:
205+
print('List is Empty!')
206+
return
207+
slow = self.head.next
208+
fast = self.head.next.next
209+
while fast != None and fast.next != None:
210+
slow = slow.next
211+
fast = fast.next.next
212+
return slow.data
213+
214+
def __dir__(self):
215+
funcs = ['insert_front', 'insert_back','pop_front','pop_back','print','len','length','remove_at','insert_after_value','index','search','reverse','mid_element','__dir__']
216+
return funcs
217+
218+
def main():
219+
ll : Node = DoublyLinkedList()
220+
221+
ll.insert_front(1)
222+
ll.insert_front(2)
223+
ll.insert_front(3)
224+
ll.insert_back(0)
225+
ll.insert_values(['ZeroTwo' , 'Asuna' , 'Tsukasa' , 'Seras'])
226+
# ll.remove_at(3)
227+
# ll.insert_at(4 , 'Raeliana')
228+
# ll.pop_back()
229+
ll.insert_after_value('Asuna' , 'MaoMao')
230+
# print(ll.search(4))
231+
# ll.remove_by_value('Asuna')
232+
# ll.reverse()
233+
# print(ll.index('ZeroTwo'))
234+
235+
ll.print()
236+
# print(ll.mid_element())
237+
# print(ll.length)
238+
# print(ll.__dir__())
239+
240+
241+
242+
243+
244+
if __name__ == '__main__':
245+
main()

0 commit comments

Comments
 (0)