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