数据结构笔记-实现链表反转 python

概述

 

这里主要针对单向链接表,单向连接表的结点是一个二元组,其中元素域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]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BIT_666

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值