IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 单链表逆转 -> 正文阅读

[数据结构与算法]单链表逆转

单链表逆转的方法有很多,我也从很多博主那学习看到了各种各样的方法。今天就给大家总结一下个人认为较简便的四种方法。这四种方法不用开辟新的空间,所以不会造成空间浪费。

方法一:迭代

?采用迭代的基本思路如下:我假设链表为1->2->3->4,那么但我完成链表的逆转后就应该是4->3->2->1。我将链表的头结点设为L,同时开辟两个新的节点q和p,我将利用L,q,p三个节点来进行迭代。

List Reverse(List L) {
		List p, q;
		p = L;
		L = NULL;
		while (p)
		{
			q = p;
			p = p->Next;
			q->Next = L;
			L = q;


		}
		return L;

	}

?代码在上面,具体的思路讲解如下:

L为头节点,把L赋值给p,而后让L为null。如下

进入while循环体进行第一次的循环,如下

当p不为空,进行第二次循环。如下

?

当p不为空,进行第三次循环,第四次.........到p为空为止。当while循环体执行到p为空的时候,这时最后一个节点为L,返回L,逆转结束。

(本质是有三个节点分别为L,q,p。进行while循环后,每次改变一个节点的方向,让原来为L->q的方向,变成q->L。然后通过迭代让q变成新的L,p变成新的q,p=p->next变成新的p,在下一个循环继续改变方向。)

?

?方法二:不同风格的迭代

第二种方法也是迭代,但和第一种方法相比会有所不同。核心思想一样,通过不断移动三个点来实现方向的转变。

头节点为L,新开辟三个新的节点空间为p,q,r。

List Reverse(List L) {
		List p, q, r;
		if (L == NULL || L->Next == NULL) //当头节点为空或者只有一个节点时直接返回头节点。
			return L;
		p = L;
		q = L->Next;
		L->Next = NULL;
		while (q) {
			r = q->Next;
			q->Next = p;
			p = q;
			q = r;
		}
		L = p;
		return L;

	
	}

?代码在上面,具体的思路讲解如下:

头节点赋给p,头节点下一个为q,然后让头节点指向null。如下

?进行第一次的循环?,如下

当q节点不为空,进行第二次循环,如下

??继续进行循环,直到当q节点为空时,这最后一个节点为p,退出循环。将p设为新的头节点L,返回L。

?方法三:

从第2个节点到第N个节点,依次逐节点插入到第1个节点(L节点)之后,最后将第一个节点挪到新表的表尾。??

List Reverse(List L) {
		if (L == NULL || L->Next == NULL)return L;//当为空链表或者只有一个节点时返回L
		List p, q;
		p = L->Next;
		while (p->Next) {
			q = p->Next;
			p->Next = q->Next;
			q->Next = L->Next;
			L->Next = q;
		}
		p->Next = L;
		L = p->Next->Next;
		p->Next->Next = NULL;
		return L;
		
	}

代码在上面,具体的思路讲解如下:

假设链表为1->2->3->4->5->6,我们的步骤如下:

?具体的步骤如下:

当开始执行时(写得有些潦草,诸位多多包涵,耐心看一定有所收获)

?当继续循环时

当循环结束时,我们会得到1->6->5->4->3->2。这明显不是我们想要的结果,但离最终结果已经很近了,我们如何将原始的头节点移到最后呢?

因为循环条件是p->next不为空,那么我们已经知道了当循环退出时最后一个节点为p。于是我们可以(1)让p->Next = L,形成一个闭环。(2)?L = p->Next->Next形成新的头节点。(3)最后用p->Next->Next = NULL来切断闭环,形成一个链表。还是有点懵?不要紧,我把图画好了!诸君请细看。

(1)让p->Next = L,形成一个闭环

?(2)?L = p->Next->Next形成新的头节点

?最后用p->Next->Next = NULL来切断闭环,形成一个链表

?最后三步的总图在这

?方法四:递归

用递归来实现代码上会相对的简单。关于递归这,我看了几篇博主的文章,有几个版本,大家看看哪个才是对的。

(1)版本一:有的博主是这样认为的,比如链表是1->2->3->4->5->6,他认为递归函数Reverse()执行完后,链表就变成了6->5->4->3->2 <-1,然后只需要改动原来的头节点就可以完成逆转。通俗的说就是不断继续递归找到新节点,然后执行递归后面的语句只执行一次改变头节点就完成了。

(2)版本二:通过不断的递归,每次递归都会执行递归后面的语句,每次改变两个节点之间的方向,从前往后改,基本是这样的1<-2->3->4->5->6,然后1<-2-<3->4->5->6,然后1<-2<-3<-4->5->6以此类推。

(3)这既然是一个有争议的地方,我个人是这样认为的,递归后的语句应该是在完成递归后再不断执行,递归多少次就执行多少次,和版本二一样,但执行的顺序我认为应该是从后往前,因为它是堆栈存储,应该遵循后进先出,所以我认为应该是1->2->3->4->5<-6,然后1->2->3->4<-5<-6,然后1->2<-3<-4<-5<-6,以此类推。

但无论是哪个版本,下面这些递归代码答案都是正确的,而且极其简短。

List Reverse(List L) {
		if (L == NULL || L->Next == NULL)return L;//当L为空或者只有L一个节点时
		List newL, q;
		newL = Reverse(L->Next);
		q = L->Next;
		q->Next = L;
		L->Next = NULL;
		return newL;

头节点为L,当逆转链表后,新的头节点为newL;

总结:上面这四种方法不用另外开辟空间,不会造成空间浪费。也是我认为较好的方法。虽然有些地方可能写的可能比较潦草,但我也是收集了几天资料,看了许多博主后个人总结写的,上面内容均为原创,个人认为也算是心血之作了,不知不觉已经2000多字了,希望能帮助到大家,大家也不要吝啬手中的赞哦,喜欢的朋友赞一个。

?

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-08-14 14:21:25  更:2021-08-14 14:23:56 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 20:38:07-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码