Python实现线性表的方法前面已经讲过,但是不带头结点会有一些问题,主要就是第一个结点的处理需要和其他结点区别对待:
为了操作上的方便,在单链表第一个结点之前增加一个结点,称为头结点。头结点的数据域可以不设任何信息,也可以记录表长等相关信息。头结点的指针域指向线性表的第一个元素结点。
不管带不带头结点,头指针始终指向链表的第一个结点,头结点是带头结点链表的第一个结点,结点内通常不存储信息
引入头结点的好处:
1)由于开始结点的位置被存放在头结点的指针域中,所以在链表的第一个位置上的操作和在表中其他位置上的操作一致,无须进行特殊处理。
2)无论链表是否为空,其头指针是指向头结点的非空指针(空表中头结点的指针域为空),因此空表和非空表的处理也就统一了。
直接上代码,其余的函数在Python实现线性表已经展示,有兴趣的可以去看看:
class linknode():#每个结点有两个数据成员,结点元素和指向下一个结点的指针
def __init__(self,item): #创建节点
self.item = item
self.next = None
class linklist():#初始化单链表,头结点指针域为空
def __init__(self):#初始化的头结点的内容为None,指针域也为None
self.headnode=linknode(None)
self.headnode.next=None
def headcreatlist(self, item):
nod = linknode(item) # 新建一个结点并赋值
nod.next = self.headnode.next # 结点指针域指向第一个结点
self.headnode.next= nod # 头结点指针指向当前结点
def tailcreatelist(self,item):
"""尾部添加元素"""
node =linknode(item)
cur = self.headnode
while cur.next != None:
cur = cur.next
cur.next = node
def listlength(self):
nod = self.headnode.next # 头结点指针域指向第一个结点
nodnum =0
while (nod != None):
nodnum += 1
nod = nod.next # 下一个结点
return nodnum
# 遍历单链表
def tralist(self):
show = []
nod = self.headnode.next
while nod != None:
show.append(nod.item)
nod = nod.next
return show
if __name__ == "__main__":
ll1=linklist()
for i in range(10):
ll1.headcreatlist(i*10)
len=ll1.listlength()
print("单链表的长度为:",len)
sh=ll1.tralist()
print("头插法建立的链表遍历为:",ll1.tralist())
ll2 = linklist()
for i in range(10):
ll2.tailcreatelist(i * 10)
len = ll2.listlength()
print("单链表的长度为:", len)
sh = ll2.tralist()
print("头插法建立的链表遍历为:", ll2.tralist())
运行结果为:
单链表的长度为: 10
头插法建立的链表遍历为: [90, 80, 70, 60, 50, 40, 30, 20, 10, 0]
单链表的长度为: 10
头插法建立的链表遍历为: [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
单链表的翻转
要实现单链表的翻转,可以遍历原链表,将每个节点的指针指向其前一个节点,从而实现链表的翻转。最后需要注意更新头节点的指针,使其指向原链表的最后一个节点。
class linknode():
def __init__(self, item):
self.item = item
self.next = None
class linklist():
def __init__(self):
self.headnode = linknode(None)
self.headnode.next = None
# 将链表中的节点值转换为列表,方便查看结果
def to_list(self):
node = self.headnode.next
result = []
while node:
result.append(node.item)
node = node.next
return result
# 在链表头部插入节点
def insert_at_head(self, item):
new_node = linknode(item)
new_node.next = self.headnode.next
self.headnode.next = new_node
# 单链表翻转
def reverse(self):
if self.headnode.next is None:
return
prev = None
current = self.headnode.next
while current:
next_node = current.next
current.next = prev
prev = current
current = next_node
self.headnode.next = prev
# 测试
ll = linklist()
ll.insert_at_head(1)
ll.insert_at_head(2)
ll.insert_at_head(3)
print("原始链表:", ll.to_list()) # 原始链表: [3, 2, 1]
ll.reverse()
print("翻转后链表:", ll.to_list()) # 翻转后链表: [1, 2, 3]
递归法实现单链表
基本思路是将链表分成头节点和剩余部分,然后递归地翻转剩余部分,并将头节点插入翻转后的链表的尾部。
class linknode():
def __init__(self, item):
self.item = item
self.next = None
class linklist():
def __init__(self):
self.headnode = linknode(None)
self.headnode.next = None
# 将链表中的节点值转换为列表,方便查看结果
def to_list(self):
node = self.headnode.next
result = []
while node:
result.append(node.item)
node = node.next
return result
# 在链表头部插入节点
def insert_at_head(self, item):
new_node = linknode(item)
new_node.next = self.headnode.next
self.headnode.next = new_node
# 递归法翻转链表
def reverse_recursive(self, head):
if head is None or head.next is None:
return head
new_head = self.reverse_recursive(head.next) # 递归翻转剩余部分
head.next.next = head # 将当前节点的下一个节点指向当前节点,实现翻转
head.next = None # 将当前节点的指针指向None,防止形成循环
return new_head
# 对外接口,调用递归函数翻转链表
def reverse(self):
self.headnode.next = self.reverse_recursive(self.headnode.next)
# 测试
ll = linklist()
ll.insert_at_head(1)
ll.insert_at_head(2)
ll.insert_at_head(3)
print("原始链表:", ll.to_list()) # 原始链表: [3, 2, 1]
ll.reverse()
print("翻转后链表:", ll.to_list()) # 翻转后链表: [1, 2, 3]
单链表的排序
class linknode():
def __init__(self, item):
self.item = item
self.next = None
class linklist():
def __init__(self):
self.headnode = linknode(None)
self.headnode.next = None
# 将链表中的节点值转换为列表,方便查看结果
def to_list(self):
node = self.headnode.next
result = []
while node:
result.append(node.item)
node = node.next
return result
# 在链表头部插入节点
def insert_at_head(self, item):
new_node = linknode(item)
new_node.next = self.headnode.next
self.headnode.next = new_node
# 单链表插入排序
def insertion_sort(self):
if self.headnode.next is None:
return
sorted_head = linknode(None)
current = self.headnode.next
while current:
prev = sorted_head
next_node = current.next
while prev.next and prev.next.item < current.item:
prev = prev.next
current.next = prev.next
prev.next = current
current = next_node
self.headnode.next = sorted_head.next
# 测试
ll = linklist()
ll.insert_at_head(3)
ll.insert_at_head(1)
ll.insert_at_head(2)
ll.insert_at_head(5)
ll.insert_at_head(4)
print("原始链表:", ll.to_list()) # 原始链表: [4, 5, 2, 1, 3]
ll.insertion_sort()
print("排序后链表:", ll.to_list()) # 排序后链表: [1, 2, 3, 4, 5]