和数组一样,链表结构表示项的线性序列,然而使用链表结构无法根据指定索引立即访问该节点,必须从结构的一端开始沿着链表进行,直达索引处,数组必须存储在连续的内存中,而链表可以不。
内存管理:python为每一个新的节点对象提供了动态分配的非连续内存,节点中的字段是数据项的一个引用和到另一个节点的一个引用,当对象不再被程序所引用时,会自动把内存返还给系统。
具体详见:
https://blog.youkuaiyun.com/jiangjiang_jian/article/details/79140742
单链表节点类
class Node(object):
def __init__(self, data,next = None):
self.data = data
self.next = next
def traversal(self, head):
probe = head
while probe != None:
print(probe.data)
probe = probe.next
def search(self, head, targetItem):
nodeNumber = 0
probe = head
while probe != None and targetItem != probe.data:
probe = probe.next
nodeNumber += 1
if probe != None:
return nodeNumber
else:
raise ValueError
def reset(self, head, index, newItem):
probe = head
while index > 0:
probe = probe.next
index -= 1
probe.data = newItem
def insert_front(self, head, newItem):
#在开始处插入
head = Node(newItem, head)
def insert_back(self, head, newItem):
#在尾部插入
newNode = Node(newItem)
if head is None:
head = newNode
else:
probe = head
while probe.next != None:
probe = probe.next
probe.next = newNode
def delete_front(self, head):
#删除头节点
removedItem = head.data
head = head.next
return removedItem
def delete_back(self, head):
#删除末尾节点
probe = head
while probe.next.next != None:
probe = probe.next
removedItem = probe.next.data
probe.next = None
return removedItem
def insert(self, head, index, newItem):
#在任意位置插入节点
if head is None or index <= 0:
head = Node(newItem, head)
else:
probe = head
while index > 1 and probe.next != None:
probe = probe.next
index -= 1
probe.next = Node(newItem, probe.next)
'''在索引处插入新的节点,首先需要找到该索引前一个节点
左侧probe.next表示在索引前一个节点后的位置插入该节点,同时前一个节点指向该新插入的节点,
右侧probe.next表示插入的新节点所指向的下一个节点,该节点为索引前一个节点原来指向的节点
'''
def delete(self, head, index):
#删除任意位置的节点
if index <= 0 or head.next is None:
#删除头节点
removedItem = head.data
head = head.next
return removedItem
else:
probe = head
while index > 1 and probe.next.next != None:
probe = probe.next
index -= 1
removedItem = probe.next.data
probe.next = probe.next.next
return removedItem
某一个节点在初始化时:node = None,此时该节点不会引用包含了一个next字段的节点对象,另外在遍历链表时,如果直接使用该链表头指针进行遍历,在这个过程最后,节点实际从链表结构中删除,对于程序来说,节点变为不可用,并且会在下一次垃圾回收的时候进行回收
链表的变体
1.含有哑头节点的循环链表:在单链表结构中,在第一个节点的插入和删除,只是在其他位置插入和删除的特殊情况(head指针需要重置),加入哑头节点,插入和删除只需要考虑一种情况
https://blog.youkuaiyun.com/huanghxyz/article/details/77487477
2.双链表结构:(data数据引用,指向前驱的previous指针,指向后继的next指针)
class Node(object):
def __init__(self, data, next = None):
self.data = data
self.next = next
class TwoWayNode(Node):
def __init__(self, data, previous = None, next = None):
super().__init__(data, next)
self.previous = previous