前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >小白学算法-数据结构和算法教程: 反转链表

小白学算法-数据结构和算法教程: 反转链表

作者头像
用户1418987
发布2023-10-26 14:17:05
1720
发布2023-10-26 14:17:05
举报
文章被收录于专栏:coder
小白学算法-数据结构和算法教程: 反转链表_反转链表
小白学算法-数据结构和算法教程: 反转链表_反转链表

反转链表链表的反转

给定一个指向链表头节点的指针,任务是反转链表。我们需要通过更改节点之间的链接来反转列表。

例子: 

输入:以下链表的头  1->2->3->4->NULL  输出:链表应更改为  4->3->2->1->NULL 输入:以下链表的头  1->2->3->4->5->NULL  输出:链表应更改为  5->4->3->2->1->NULL 输入:NULL  输出:NULL 输入:1->NULL  输出:1->NULL 

通过迭代法反转链表:

这个想法是使用三个指针currprevnext来跟踪节点以更新反向链接。

插图:
小白学算法-数据结构和算法教程: 反转链表_初始化_02
小白学算法-数据结构和算法教程: 反转链表_初始化_02

请按照以下步骤解决问题:

  • 将三个指针prev初始化为 NULL,将 curr 初始化head将 next初始化为 NULL。
  • 遍历链表。在循环中,执行以下操作:
  • 在更改curr下一个之前,存储一个节点 
  • 下一个 = 当前 -> 下一个
  • 现在将currnext指针更新为prev
  • 当前 -> 下一个 = 上一个 
  • 将prev更新为curr,将curr 更新为next
  • 上一个 = 当前 
  • 当前 = 下一个

下面是上述方法的实现:

代码语言:javascript
复制
#Python程序用于反转链表
#时间复杂度:O(n)
#空间复杂度:O(1)

#节点类
class Node:
	# 初始化节点对象的构造函数
	def __init__(self, data):
		self.data = data
		self.next = None


class LinkedList:

	#初始化头部的函数
	def __init__(self):
		self.head = None

	# 反转链接列表的函数
	def reverse(self):
		prev = None
		current = self.head
		while(current is not None):
			next = current.next
			current.next = prev
			prev = current
			current = next
		self.head = prev

	# 在开头插入新节点的函数
	def push(self, new_data):
		new_node = Node(new_data)
		new_node.next = self.head
		self.head = new_node

	# 打印 LinkedList 的实用程序
	def printList(self):
		temp = self.head
		while(temp):
			print(temp.data, end=" ")
			temp = temp.next


# Driver code
llist = LinkedList()
llist.push(20)
llist.push(4)
llist.push(15)
llist.push(85)

print ("Given linked list")
llist.printList()
llist.reverse()
print ("\nReversed linked list")
llist.printList()
输出
代码语言:javascript
复制
给定链表
85 15 4 20 
反向链表
20 4 15 85

时间复杂度: O(N),遍历大小为N的链表。  辅助空间: O(1)

使用递归反转链表:

这个想法是使用递归到达链表的最后一个节点,然后开始反转链表。

插图:
小白学算法-数据结构和算法教程: 反转链表_初始化_03
小白学算法-数据结构和算法教程: 反转链表_初始化_03

请按照以下步骤解决问题:

  • 将链表分为两部分——第一个节点和链表的其余部分。
  • 对链表的其余部分调用reverse。
  • 将其余链表链接到第一个。
  • 将头指针修复为 NULL

下面是上述方法的实现:

代码语言:javascript
复制
"""使用递归方法反转链接表的 Python3 程序
使用递归方法"""

# 链接列表节点

class Node:
	def __init__(self, data):
		self.data = data
		self.next = None

# 创建和处理列表操作

class LinkedList:
	def __init__(self):
		self.head = None # 列表的头部

	# 反转列表的方法
	def reverse(self, head):

		# 如果头部为空或已到达列表末尾
		if head is None or head.next is None:
			return head

		# 倒转其余列表
		rest = self.reverse(head.next)

		# 将第一个元素放在最后
		head.next.next = head
		head.next = None

		# 修复头部指针
		return rest

	# 返回显示格式的链接列表
	def __str__(self):
		linkedListStr = ""
		temp = self.head
		while temp:
			linkedListStr = (linkedListStr +
							str(temp.data) + " ")
			temp = temp.next
		return linkedListStr

	# 将新数据推送到列表头部
	def push(self, data):
		temp = Node(data)
		temp.next = self.head
		self.head = temp

linkedList = LinkedList()
linkedList.push(20)
linkedList.push(4)
linkedList.push(15)
linkedList.push(85)

print("Given linked list")
print(linkedList)

linkedList.head = linkedList.reverse(linkedList.head)

print("Reversed linked list")
print(linkedList)

输出

代码语言:javascript
复制
给定链表
85 15 4 20
反向链表
20 4 15 85

时间复杂度: O(N),每个节点访问一次辅助空间: O(N),函数调用栈空间

通过尾递归方法反转链表:

这个想法是维护三个指针previouscurrentnext,递归访问每个节点并使用这三个指针建立链接。

请按照以下步骤解决问题:

  • 首先用当前的下一个节点更新下一个,即next = current->next
  • 现在建立从当前节点到前一个节点的反向链接,即 curr->next = prev
  • 如果访问的节点是最后一个节点,则只需从当前节点到前一个节点进行反向链接并更新头。 

下面是上述方法的实现:

代码语言:javascript
复制
#简单的尾递归Python程序,用于反转链表

#节点类
class Node:

	# 用于初始化节点对象的构造函数
	def __init__(self, data):
		self.data = data
		self.next = None


class LinkedList:

	# 初始化头部的函数
	def __init__(self):
		self.head = None

	def reverseUtil(self, curr, prev):

		# 如果是最后一个节点,将其标记为头
		if curr.next is None:
			self.head = curr

			# 更新前一个节点的下一个节点
			curr.next = prev
			return

		# 保存 curr.next 节点以供递归调用
		next = curr.next

		# 并更新下一步
		curr.next = prev

		self.reverseUtil(next, curr)

# 该函数主要调用 reverseUtil()
# 将 previous 设为 None

	def reverse(self):
		if self.head is None:
			return
		self.reverseUtil(self.head, None)

	# 在开头插入新节点的函数

	def push(self, new_data):
		new_node = Node(new_data)
		new_node.next = self.head
		self.head = new_node

	# 打印链接的 LinkedList 的实用程序
	def printList(self):
		temp = self.head
		while(temp):
			print (temp.data, end=" ")
			temp = temp.next


# Driver code
llist = LinkedList()
llist.push(8)
llist.push(7)
llist.push(6)
llist.push(5)
llist.push(4)
llist.push(3)
llist.push(2)
llist.push(1)

print ("Given linked list")
llist.printList()

llist.reverse()

print ("\nReversed linked list")
llist.printList()

输出

代码语言:javascript
复制
给定链表
1 2 3 4 5 6 7 8 
反向链表
8 7 6 5 4 3 2 1

时间复杂度: O(N),访问大小为 N 的链表的每个节点。 辅助空间: O(N),函数调用栈空间

使用Stack反转链表:

这个想法是将所有节点存储在堆栈中,然后创建一个反向链表。

请按照以下步骤解决问题:

  • 将节点(值和地址)存储在堆栈中,直到输入所有值。
  • 一旦所有条目完成,将头指针更新到最后一个位置(即最后一个值)。
  • 开始弹出节点(值和地址)并以相同的顺序存储它们,直到堆栈为空。
  • 将堆栈中最后一个节点的下一个指针更新为 NULL。

下面是上述方法的实现:

代码语言:javascript
复制
# 上述方法的 Python 代码

# 单链表的定义。
class ListNode:
	def __init__(self, val=0, next=None):
		self.val = val
		self.next = next


class Solution:

	# 反转链接列表的程序使用堆栈
	def reverseLLUsingStack(self, head):

		# 初始化变量
		stack, temp = [], head

		while temp:
			stack.append(temp)
			temp = temp.next

		head = temp = stack.pop()

		# 直到堆栈不空
		while len(stack) > 0:
			temp.next = stack.pop()
			temp = temp.next

		temp.next = None
		return head


if __name__ == "__main__":
	head = ListNode(1, ListNode(2, ListNode(3, ListNode(4))))
	print("Given linked list")
	temp = head
	while temp:
		print(temp.val, end=' ')
		temp = temp.next
	obj = Solution()
	print("\nReversed linked list")
	head = obj.reverseLLUsingStack(head)
	while head:
		print(head.val, end=' ')
		head = head.next

输出

代码语言:javascript
复制
给定链表
1 2 3 4 
反向链表
4 3 2 1

时间复杂度: O(N),访问大小为N的链表的每个节点。 辅助空间: O(N),空间用于存储堆栈中的节点。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-10-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 反转链表链表的反转
  • 通过迭代法反转链表:
    • 插图:
      • 输出
      • 使用递归反转链表:
        • 插图:
        • 通过尾递归方法反转链表:
        • 使用Stack反转链表:
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档