'''
链式与线性结构的区别:
线性————内存连续、下标访问;
链式————内存不连续、无下标,追加时很方便,寻找的话很麻烦需要遍历。
'''
#定义节点(具有value和next属性,值和指针)
class Node(object):
def __init__(self,value=None,next=None):
self.value = value
self.next = next
#定义单链表
class LinkedList(object):
def __init__(self,max_size=None):
self.max_size = max_size
self.root = Node()
self.length = 0
self.tail_node = None
def __len__(self):
return self.length
def append(self,value):
if self.max_size is not None and len(self) > self.max_size:
raise Exception("Full")
node = Node(value)
tail_node = self.tail_node
if tail_node is None: #只有根节点
self.root.next = node
else:
tail_node.next = node
self.tail_node = node
self.length += 1
def append_left(self,value):
"""插入到root节点的后边"""
head_node = self.root.next #构造头结点
node = Node(value)
self.root.next = node
node.next = head_node #把当前节点的下一个节点再指向头结点
self.length += 1
def iter_node(self):
"""遍历从head节点到tail节点"""
curr_node = self.root.next
while curr_node is not self.tail_node:
#只要不是尾节点就yield当前节点
yield curr_node
curr_node = curr_node.next #更新成下一个节点
yield curr_node
def __iter__(self):
for node in self.iter_node():
yield node.value
def remove(self,value): #O(n)
"""删除包含值的一个节点,将其前一个节点的next指向被查询节点的下一个即可"""
prev_node = self.root
curr_node = self.root.next
for curr_node in self.iter_node():
if curr_node.value == value:
#查找到时,当前节点指向当前节点的下一个节点
prev_node.next = curr_node.next
if curr_node is self.tail_node:
self.tail_node = prev_node #注意更新tail_node
del curr_node
self.length -= 1
return 1
else:
prev_node = curr_node #更新prev_node
return -1
def find(self,value): #O(n)
index = 0
for node in self.iter_node():
if node.value == value:
return index
index += 1
return -1
def pop_left(self): #O(1)
if self.root.next is None:
raise Exception("Pop from empty LinkedList.")
head_node = self.root.next
self.root.next = head_node.next #头结点指向头结点的下一个节点
self.length -= 1
value = head_node.value
del head_node
return value
def clear(self):
for node in self.iter_node():
del node
self.root.next = None
self.length = 0
def test_linkedNode():
ll = LinkedList()
ll.append(0)
ll.append(1)
ll.append(2)
ll.append(3)
assert len(ll) == 4
assert ll.find(2) == 2
ll.remove(0)
assert len(ll) == 3
ll.append_left(0)
assert list(ll) == [0,1,2,3]
test_linkedNode()