Python實現列表和鏈表
list[index] O(1)
list.append O(1)
list.insert O(n)
list.pop(index) 默認刪last O(1)
list.remove(element) O(n)
class Array(object):
def __init__(self, size=32):
self._size = size
self._items = [None] * self._size
def __getitem__(self, index):
return self._items[index]
def __setitem__(self, index, value):
self._items[index] = value
def __len__(self):
return self._size
def clear(self, value=None):
for i in range(len(self._items)):
self._items[i] = value
def __iter__(self):
for item in self._items:
yield item
單鏈表
缺點:1. remove時是O(n) 2.只能單向遍歷
linked_list.append(value) O(1)
linked_list.appendleft(value) O(1)
linked_list.find(value) O(n)
linked_list.remove(value) O(n)
class Node(object):
def __init__(self, value=None, next=None):
self.value, self.next = value, next
class LinkedList(object):
def __init__(self, msxsize=None):
# msxsize=None代表無限大
self.maxsize = msxsize
# self.root 是根節點,根節點的next一般指向頭節點head節點
self.root = Node()
self.length = 0
# self.tailnode表示最后一個節點
self.tailnode = None
def __len__(self):
return self.length
def append(self, value):
# 判斷當前最大值是否超過了允許的最大值
if self.maxsize is not None and len(self) > self.maxsize:
raise Exception("Full")
node = Node(value)
tailnode = self.tailnode
if tailnode is None:
# 表明現在只有一個root節點, 然后指向當前的node節點即可
self.root.next = node
else:
# 否則把最后一個節點的next指向當前的node節點
self.tailnode.next = node
# 更新最后一個節點為node,因為我們把node放到了最后,而self.tailnode代表最后一個節點,所以要更新
self.tailnode = node
# 鏈表長度加一
self.length += 1
def appendleft(self, value):
# 定義頭節點
headnode = self.root.next
node = Node(value)
# 根節點指向新的head節點: node節點
self.root.next = node
# node節點指向之前的head節點
node.next = headnode
self.length += 1
def iter_node(self):
# 第一個節點
curnode = self.root.next
# 當前節點不是最后一個節點時
while curnode is not self.tailnode:
yield curnode
# 當前節點更新為下一個節點
curnode = curnode.next
# 尋找到最后節點時,也需要把最后一個節點yield出來
yield curnode
def __iter__(self):
for node in self.iter_node():
yield node.value
def remove(self, value):
"""
刪除包含值的一個節點,將其前一個節點的next指向下一個節點即可 O(n)
:param value:
:return:
"""
# 根節點
prevnode = self.root
for curnode in self.iter_node():
if curnode.value == value:
prevnode.next = curnode.next
if curnode is self.tailnode:
# 注意更新 tailnode
self.tailnode = prevnode
del curnode
self.length -= 1
# 返回1代表成功
return 1
else:
# 更新 prevnode
prevnode = curnode
# 返回-1表示刪除失敗
return -1
def find(self, value):
# O(n)
index = 0
for node in self.iter_node():
if node.value == value:
return index
index += 1
# 返回-1表示沒找到
return -1
def popleft(self):
# O(1)
if self.root.next is None:
raise Exception("pop from empty LinkedList")
headnode = self.root.next
# 根節點指向頭節點的下一個節點
self.root.next = headnode.next
value = headnode.value
self.length -= 1
del headnode
return value
def clear(self):
for node in self.iter_node():
del node
self.root.next = None
self.length = 0
雙端鏈表
class Node(object):
def __init__(self, value=None, prev=None, next=None):
self.value, self.prev, self.next = value, prev, next
class CirculaDoubleLinkedList(object):
def __init__(self, msxsize=None):
# msxsize=None代表無限大
self.maxsize = msxsize
node = Node()
node.next, node.prev = node, node
self.root = node
self.length = 0
def __len__(self):
return self.length
def headnode(self):
return self.root.next
def tailnode(self):
# 根節點的prev指向尾節點
return self.root.prev
def append(self, value):
# 判斷當前最大值是否超過了允許的最大值
if self.maxsize is not None and len(self) > self.maxsize:
raise Exception("Full")
node = Node(value=value)
tailnode = self.tailnode()
# 最后一個節點指向新的最后節點
tailnode.next = node
# 新的最后節點指向前節點
node.prev = tailnode
# node的下一個節點指向root
node.next = self.root
# 根節點的上一個節點指向新的最后節點,形成閉環
self.root.prev = node
self.length += 1
def appendleft(self, value):
# 判斷當前最大值是否超過了允許的最大值
if self.maxsize is not None and len(self) > self.maxsize:
raise Exception("Full")
node = Node(value=value)
# 如果根節點的下一個節點是自己,則證明是空的
if self.root.next is self.root:
# 新節點的下一個指向根節點
node.next = self.root
# 新節點的上一個指向根節點
node.prev = self.root
# 根節點的下一個指向新節點
self.root.next = node
# 根節點的上一個指向新節點
self.root.prev = node
else:
# 新節點的上一個節點指向根節點
node.prev = self.root
# 獲取頭節點
headnode = self.headnode()
# 新節點的下一個指向頭節點
node.next = headnode
# 頭節點的上一個指向新節點
headnode.prev = node
# 根節點的下一個指向新節點
self.root.next = node
self.length+=1
def remove(self, node):
# O(1) node is not value
if node is self.root:
return
else:
# 被刪除節點的上一個節點的next指向被刪除節點的下一個節點
node.prev.next = node.next
# 被刪除節點的下一個節點的prev指向被刪除節點的上一個節點
node.next.prev = node.prev
self.length -= 1
return node
def iter_node(self):
if self.root.next is self.root:
return
curnode = self.root.next
while curnode is not self.root:
yield curnode
curnode = curnode.next
yield curnode
def __iter__(self):
for node in self.iter_node():
yield node.value
def iter_node_reverse(self):
if self.root.next is self.root:
return
curnode = self.root.prev
while curnode is not self.root:
yield curnode
curnode = curnode.prev
yield curnode