概述
这里主要针对单向链接表,单向连接表的结点是一个二元组,其中元素域elem保存着作为表元素的数据项,连接域next包含着同一个表里下一个节点的标识。在最常见的单链表里,与表里n个元素对应的n个结点通过连接形成一条结点链,从表中任一结点可以找到保存着该标的下一个元素的结点,这样从头结点p出发,就能到达表里任意一个节点。
单链表
△一个单链表由一些具体的表结点构成
△每个结点是一个对象,有自己的标识(即链接域)
△结点之间通过结点链接建立起单向的顺序联系
1.实现简单的单链表
#定义一个链表基础结构,节点包含数据信息与下一个指向的位置
class LNode:
def __init__(self,x,next_=None):
self.data = x
self.next = next_
为链表添加10个元素
llist1 = LNode(1)
p = llist1
for i in range(2,11):
p.next = LNode(i)
p = p.next
p = llist1
while p is not None:
print(p.data)
p = p.next
1 2 3 4 5 6 7 8 9 10
2.实现链表的逆序
给定一个带箭头的单链表,head→1→2→3→4→5→6→7→8→9→10,逆序后变为head→10→9→8→7→6→5→4→3→2→1
方法一:就地逆序
主要思路:
遍历链表时,修改指针域的方向,假设当前节点为cur,当前节点前一个节点为pre,后一个节点为next,指向顺序为pre→cur→next ,实现反转首先记录cur的next_域的指向(即next),将cur的next_指向pre(之前是pre的next_指向cur),此时为pre←cur,并记录了cur的下一位是next,然后将pre,cur,next顺序往后移动一位,和上述方法一样,直到最后一个节点,将head头结点指向最后的一个结点,即完成逆序。
实现:
#时间复杂度O(N) 遍历一次链表 空间复杂度 O(1)需要一个额外的地址存储后一结点
#对单链表进行逆序 输入:head链表头结点
def Reverse1(head):
#判断链表是否为空
if head == None or head.next == None:
return
pre = None #前驱结点
cur = None #当前节点
next = None #后续节点
#把链表首节点变为尾节点
cur = head.next
next = cur.next
cur.next = None
pre = cur
cur = next
#当前遍历到的节点cur指向其前驱结点
while cur.next != None:
next = cur.next
cur.next = pre
pre = cur
cur = cur.next
cur = next
#链表最后一个节点指向倒数第二个节点
cur.next = pre
#链表的头结点指向当前最后一个节点
head.next = cur
性能分析:
只需要遍历一次链表,但每次需要一个位置存储next的信息,因此时间复杂度O(N),空间复杂度O(1)
方法二:插入法
主要思路:
从链表的第二个结点开始,把遍历到的结点依次加入到头结点之后,再令他指向之前的结点。例如当前为1→2→3,从第二个节点开始,,cur为2,2的next_为3,2的pre为1,首先记录2的next_,然后将头节点改为2,将2的next_改为1,然后遍历到2的next_3,cur为3,3的pre是2,将3的next_指向2,此时3的next为None,因此停止,完成逆序,此时为3→2→1
实现:
# #方法二:插入法
def Reverse3(head):
#判断链表是否为空
if head is None or head.next is None:
return
cur = None#当前结点
next = None#后继结点
cur = head.next.next
#设置链表第一个结点为尾结点
head.next.next = None
#吧遍历到的结点插入到头结点的后面
while cur is not None:
next = cur.next
cur.next = head.next
head.next = cur
cur = next
#递归输出
def ReversePrint(firstNode):
if firstNode is None:
return
ReversePrint(firstNode.next)
print(firstNode.data)
性能分析:
只需要一次遍历,无需保存pre的信息,只需使用现成的next_域,然后修改头结点的信息即可,时间复杂度度为O(N)。
运行:
if __name__ =='__main__':
i = 1
#链表头结点
head = LNode(None)
head.next = None
tmp = None
cur = head
#构造单链表
while i<11:
tmp = LNode(None)
tmp.data = i
tmp.next = None
cur.next = tmp
cur = tmp
i += 1
# ReversePrint(head)
print("逆序前: ")
cur = head.next
while cur != None:
print(cur.data,end=' ')
cur = cur.next
print()
print("逆序后: ")
Reverse3(head)
cur = head.next
while cur != None:
print(cur.data,end=' ')
cur = cur.next
print()
逆序前:
1 2 3 4 5 6 7 8 9 10
逆序后:
10 9 8 7 6 5 4 3 2 1
[Finished in 0.1s]