-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathdouble_link_list.py
More file actions
158 lines (134 loc) · 4.26 KB
/
double_link_list.py
File metadata and controls
158 lines (134 loc) · 4.26 KB
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
from __future__ import unicode_literals
class Node(object):
def __init__(self, val, prev=None, next_=None):
self.val = val
self.prev = prev
self.next = next_
def __repr__(self):
"""Print representation of node."""
return "{val}".format(val=self.val)
class DoubleLinkList(object):
"""Class for a doubly-linked list."""
def __init__(self, iterable=()):
self._current = None
self.head = None
self.tail = None
self.length = 0
for val in reversed(iterable):
self.insert(val)
def __repr__(self):
"""Print representation of DoubleLinkList."""
node = self.head
output = ""
for node in self:
output += "{!r}, ".format(node.val)
return "({})".format(output.rstrip(' ,'))
def __len__(self):
return self.length
def __iter__(self):
if self.head is not None:
self._current = self.head
return self
def next(self):
if self._current is None:
raise StopIteration
node = self._current
self._current = self._current.next
return node
def size(self):
"""Return current length of DoubleLinkList."""
return len(self)
def search(self, search_val):
"""Return the node containing val if present, else None.
args:
search_val: the value to search by
returns: a node object or None
"""
for node in self:
if node.val == search_val:
return node
else:
return None
def remove(self, search_val):
"""Remove the first node from list matching the search value.
args:
search_val: the val to be removed
"""
search_node = self.search(search_val)
if search_node == self.head:
self.head = search_node.next
try:
self.head.prev = None
except AttributeError:
pass
self.length -= 1
elif search_node == self.tail:
self.tail = search_node.prev
try:
self.tail.next = None
except AttributeError:
pass
self.length -= 1
else:
for node in self:
if node == search_node:
node.prev.next = node.next
node.next.prev = node.prev
self.length -= 1
return None
raise ValueError('value not in list')
def insert(self, val):
"""Insert value at head of list.
args:
val: the value to add
"""
old_head = self.head
self.head = Node(val, prev=None, next_=old_head)
if old_head is None:
self.tail = self.head
else:
old_head.prev = self.head
self.length += 1
return None
def append(self, val):
"""Append a node with value to end of list.
args:
val: the value to add
"""
old_tail = self.tail
self.tail = Node(val, prev=old_tail, next_=None)
if old_tail is None:
self.head = self.tail
else:
old_tail.next = self.tail
self.length += 1
return None
def pop(self):
"""Pop the first val off the head and return it."""
if self.head is None:
raise IndexError('pop from empty list')
else:
to_return = self.head
self.head = to_return.next
try:
self.head.prev = None
except AttributeError: # List is now empty
self.tail = None
self.length -= 1
return to_return.val
def shift(self):
"""Remove the last value from the tail and return."""
if self.tail is None:
raise IndexError('pop from empty list')
else:
to_return = self.tail
self.tail = to_return.prev
try:
self.tail.next = None
except AttributeError: # List is now empty
self.head = None
self.length -= 1
return to_return.val
def display(self):
"""Shows representation of DoubleLinkList."""
return repr(self)