-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLinkedList.py
134 lines (121 loc) · 3.52 KB
/
LinkedList.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
class Node:
def __init__(self, value):
self.value = value
self.next = None
class LinkedList:
def __init__(self, value):
new_node = Node(value)
self.head = new_node
self.tail = new_node
self.length = 1
def print_list(self):
temp = self.head
while temp is not None:
print(temp.value)
temp = temp.next
def append(self, value):
# appending is O(1) due to the simple changing of tail pointer
new_node = Node(value)
if self.head is None:
self.head = new_node
self.tail = new_node
else:
self.tail.next = new_node
self.tail = new_node
self.length += 1
return True
def pop(self):
# popping is O(n) because you need to iterate through the list to find the second to last value
if self.head is None:
return None
elif self.length == 1:
right = self.head
self.head = None
self.tail = None
else:
left, right = self.head, self.head.next
while right is not self.tail:
left = left.next
right = right.next
self.tail = left
self.tail.next = None
self.length -= 1
return right
def prepend(self, value):
# O(1)
new_node = Node(value)
new_node.next = self.head
self.head = new_node
if self.tail is None:
self.tail = new_node
self.length += 1
return True
def pop_first(self):
# O(1) since the second element is easily accessible
temp = self.head
if self.head is None:
return None
elif self.length == 1:
self.head = None
self.tail = None
else:
self.head = self.head.next
temp.next = None
self.length -= 1
return temp
def get(self, index):
# O(n)
if index < 0 or index >= self.length:
return None
current = self.head
for _ in range(index):
current = current.next
return current
def set_value(self, index, value):
node = self.get(index)
if node:
node.value = value
return True
return False
def insert(self, index, value):
# O(n) to iterate through the list
left = self.get(index-1)
if index == 0:
return self.prepend(value)
elif index == self.length:
return self.append(value)
elif left:
new_node = Node(value)
new_node.next = left.next
left.next = new_node
self.length += 1
return True
return False
def remove(self, index):
# O(n) to find item
if index == 0:
return self.pop_first()
elif index == self.length - 1:
return self.pop()
elif index < 0 or index >= self.length:
return None
left = self.get(index-1)
right = left.next
left.next = right.next
right.next = None
self.length -= 1
return True
def reverse(self):
if self.head is None:
return None
elif self.length == 1:
return True
temp = self.head
self.head = self.tail
self.tail = temp
left = None
for _ in range(self.length):
right = temp.next
temp.next = left
left = temp
temp = right