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 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> get 到O(1)反转链表(尾插法)的那个点 -> 正文阅读

[数据结构与算法]get 到O(1)反转链表(尾插法)的那个点

其实一直没完全搞明白这个尾插法。也曾自己写过好多次的原地反转链表,无不以失败告终,最后不得不在O(N)的复杂度下草草收场。
背题吧,咱也不是那块料、

今晚突然就 get 到那个点了,原来,奥妙在这里···


放码过来

极简主义,类就随意吧。

#include<iostream>
using namespace std;

class Node {
public:
	Node* next;	//直接放公有域里吧,省的麻烦
	int val;

	Node(int v) { val = v; }
	Node(){}
};

Node* func(Node* head) {
	Node* nowHead = head, * sourceLink = head->next, * tempNode = NULL;
	while (sourceLink != NULL)
	{
		tempNode = sourceLink;                  // 把源链表首节点取出
		sourceLink = sourceLink->next;          // 源链表首节点后移
		tempNode->next = nowHead;               // 取出的节点接在目标链表的首部
		nowHead = tempNode;                     // 目标链表首部更改为新的节点
	}
	head->next = NULL;                        // 别忘了把原先的链表头指向NULL
	return nowHead;
}
	

int main() {
	Node* node1 = new Node(1);
	Node* node2 = new Node(2);
	Node* node3 = new Node(3);
	Node* node4 = new Node(4);

	node1->next = node2;
	node2->next = node3;
	node3->next = node4;

	Node* node = func(node1);

	while (node) {
		cout << node->val << endl;
		node = node->next;
	}

	return 0;
}

成环

自己写的每次都会打结,成环了。

Node* func(Node* head) {
	Node* nowHead = head, * sourceLink = head->next, * tempNode = NULL;
	while (sourceLink != NULL)
	{
		tempNode = sourceLink;                  // 把源链表首节点取出
		sourceLink = sourceLink->next;          // 源链表首节点后移
		tempNode->next = nowHead;               // 取出的节点接在目标链表的首部
		nowHead = tempNode;                     // 目标链表首部更改为新的节点
	}
	head->next = NULL;                        // 别忘了把原先的链表头指向NULL
	return nowHead;
}

这个就不会成环吗?一眼我就看出来会成环。
只要有这一行在,就绝对是要成环的:

tempNode->next = nowHead;

为什么?经验,自己想想。


破解

其实知道它会成环,在看两眼,也就看到玄机了。

成环有几个问题存在?
1、死循环,稍微学过链表都应该要知道这个吧。
2、无法联系到后面的节点。

先不管第一点,能想到第二点,就明白了。
我在你成环之前把后面被环屏蔽的节点事先取出来,在你成环之后重新给你接上去,破坏你的闭环。

关键就在这一行的位置:

sourceLink = sourceLink->next;

晚写一步,就玩不转了。


调试验证

那么,现在用眼睛看出来的有:
1、取出环后节点;
2、反转成环;
3、破坏闭环;
4、返回第一步,直到退出条件成立。

初始状态:
在这里插入图片描述

取出后面的节点:
在这里插入图片描述

在这里插入图片描述

依旧是要成环的:
在这里插入图片描述

看到没,依旧是要成环的。

那最后呢?

在这里插入图片描述

最后一个节点是谁?是head。
所以最后的善后操作谁来,head来,把环收了:

head->next = NULL;

全程就是这么的一气呵成,再也不用去死记硬背了。

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-09-24 10:50:25  更:2021-09-24 10:50:30 
 
开发: 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年5日历 -2024/5/17 12:55:54-

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