-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCircularSinglyLinkedListNew.py
222 lines (188 loc) · 6.15 KB
/
CircularSinglyLinkedListNew.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
class Node:
def __init__(self, value):
self.value = value
self.next = None
def __str__(self):
return str(self.value)
class CSLinkedList:
# def __init__(self, value):
# new_node = Node(value)
# new_node.next = new_node
# self.head = new_node
# self.tail = new_node
# self.length = 1
def __init__(self):
self.head = None
self.tail = None
self.length = 0
def __str__(self):
temp_node = self.head
result = ''
while temp_node is not None:
result += str(temp_node.value)
temp_node = temp_node.next
if temp_node == self.head: # Stop condition for circular list
break
result += ' -> '
return result
def append(self, value):
new_node = Node(value)
if self.length == 0:
self.head = new_node
self.tail = new_node
new_node.next = new_node
else:
self.tail.next = new_node
new_node.next = self.head
self.tail = new_node
self.length += 1
def prepend(self, value):
new_node = Node(value)
if self.length == 0:
self.head = new_node
self.tail = new_node
new_node.next = new_node
else:
new_node.next = self.head
self.head = new_node
self.tail.next = new_node # Pointing the tail's next to the new head
self.length += 1
def insert(self, index, value):
if index < 0 or index > self.length: # Check for out of range
raise Exception("Index out of range")
new_node = Node(value)
if index == 0:
if self.length == 0: # if list is empty
self.head = new_node
self.tail = new_node
new_node.next = new_node
else:
new_node.next = self.head
self.head = new_node
self.tail.next = new_node # Update tail's next for circularity
elif index == self.length:
self.tail.next = new_node
new_node.next = self.head
self.tail = new_node
else:
temp_node = self.head
for _ in range(index-1):
temp_node = temp_node.next
new_node.next = temp_node.next
temp_node.next = new_node
self.length += 1
def traverse(self):
if not self.head: # If the list is empty
return
current = self.head
while current is not None:
print(current.value)
current = current.next
if current == self.head: # Stop condition for circular list
break
def search(self, target):
current = self.head
while current is not None:
if current.value == target:
return True
current = current.next
if current == self.head: # Stop condition for circular list
break
return False
def search(self, target):
current = self.head
index = 0
while current is not None:
if current.value == target:
return index
current = current.next
index += 1
return -1
def get(self, index):
if index == -1:
return self.tail
elif index < -1 or index >= self.length:
return None
current = self.head
for _ in range(index):
current = current.next
return current
def set_value(self, index, value):
temp = self.get(index)
if temp:
temp.value = value
return True
return False
def pop_first(self):
if self.length == 0:
return None
popped_node = self.head
if self.length == 1:
self.head = None
self.tail = None
else:
self.head = self.head.next
self.tail.next = self.head # Update the tail's next pointer to point to the new head
popped_node.next = None
self.length -= 1
return popped_node
def pop(self):
if self.length == 0:
return None
popped_node = self.tail
if self.length == 1:
self.head = self.tail = None
else:
temp = self.head
while temp.next is not self.tail:
temp = temp.next
temp.next = None
self.tail = temp
self.length -= 1
return popped_node
def pop(self):
if self.length == 0:
return None
popped_node = self.tail
if self.length == 1:
self.head = None
self.tail = None
else:
temp = self.head
while temp.next != self.tail: # Traverse until the second last node
temp = temp.next
temp.next = self.head # Pointing the second last node's next to the head
self.tail = temp # Updating the tail to be the second last node
popped_node.next = None
self.length -= 1
return popped_node
def remove(self, index):
if index < -1 or index >= self.length:
return None
if index == 0:
return self.pop_first()
if index == -1 or index == self.length-1:
return self.pop()
prev_node = self.get(index-1)
popped_node = prev_node.next
prev_node.next = popped_node.next
popped_node.next = None
self.length -= 1
return popped_node
def delete_all(self):
if self.length == 0:
return # If the list is empty, just return
self.tail.next = None # Breaking the circular link
self.head = None
self.tail = None
self.length = 0
linked_list = CSLinkedList()
print(linked_list)
linked_list.append(10)
linked_list.insert(0,20)
linked_list.insert(1,30)
linked_list.insert(2,40)
linked_list.insert(3,50)
print(linked_list)
print(linked_list.set_value(-1,100))
print(linked_list)