🥳每日一练-反转链表-JS简易版

今天要分享的内容是反转链表。这是一个很经典的问题,将一个单指针链表从头指向尾的顺序改成从尾指向头

像下面这样:

变成:

问题很清晰,也很简单,我们来看有哪些解法:

准备数据

javascript 复制代码
const data = [1, 2, 3, 4, 5];
const generateList = (data) => {
	const root = { next: null };
	let node = root;
	data.forEach((item) => {
		const temp = { value: item, next: null };
		node.next = temp;
		node = node.next;
	});
	return root.next;
};

const linkList = generateList(data);

上面代码生成了有五个节点的单链表。链表从 1 到 5。

再准备一个输出链表的方法,用来验证链表是否正确

javascript 复制代码
const printLink = (data) => {
	let node = data;
	while (node) {
		console.log(node.value);
		node = node.next;
	}
};

printLink(linkList);
// 1
// 2
// 3
// 4
// 5

没有问题

反转链表

方法一

javascript 复制代码
// 定义一个函数 reverseLink,接收一个链表作为参数
const reverseLink = (linkList) => {
    // 初始化一个节点指针 node 指向链表的头结点
    let node = linkList;
    // 初始化一个空节点指针 pre 指向 null
    let pre = null;
    // 使用 while 循环遍历链表,直到链表为空
    while (node) {
        // 保存当前节点的下一个节点指针 next
        const next = node.next;
        // 将当前节点的下一个节点指针指向 pre
        node.next = pre;
        // 将 pre 指针指向当前节点
        pre = node;
        // 将 node 指针指向下一个节点
        node = next;
    }
    // 返回反转后的链表头结点
    return pre;
};

逻辑比较简单,从头到尾依次遍历,依次让 node 的 next 指针指向 pre,然后 pre 和 node 分别往后挪动一个位置。直到 node 挪成 null,也就是 pre 挪到了链表的最后一个位置,就停止遍历。并且返回反转之后链表的头节点

测试代码:

javascript 复制代码
printLink(reverseLink(linkList));
// 5
// 4
// 3
// 2
// 1

方法二:

还可以用递归的方式来解决:

javascript 复制代码
// 定义一个函数 reverseLink2,接收一个链表作为参数
const reverseLink2 = (linkList) => {
    // 如果链表为空或只有一个节点,直接返回链表
    if (!linkList || !linkList.next) return linkList;
    // 递归调用 reverseLink 函数,直到链表的最后一个节点
    const lastNode = reverseLink(linkList.next);
    // 将链表的下一个节点的下一个节点指针指向当前节点
    linkList.next.next = linkList;
    // 将当前节点的下一个节点指针指向 null
    linkList.next = null;
    // 返回反转后的链表的头结点
    return lastNode;
};

这个方法的构思就比较巧妙。将调整的位置直接从链表的尾部开始,将一个个节点由后指向前。

帮助理解:

  1. 假设我们已经来到了最后一个 node,也就是 linkList == 节点 5,这时候第一个判断会直接将节点 5 返回
  2. 然后我们就回到了上一层调用的第 6 行代码。在这一层 linkList == 节点 4,lastNode 会是节点 5 。 继续往下执行。下面两行代码的作用是将节点 5 的 next 指针指向 4,并且节点 4 的指针指向 null。最后返回节点 5
  3. 然后又回到了上一层调用的第 6 行代码。在这一层 linkList == 节点 3。lastNode 依旧是节点 5 。继续往下执行。下面两行代码的作用是将节点 4 的 next 指针指向 3,并且节点 3 的指针指向 null。最后返回节点 5
  4. 依次类推

测试代码:

javascript 复制代码
printLink(reverseLink2(linkList));
// 5
// 4
// 3
// 2
// 1

方法三

还有种方法,就是遍历 linkList,然后将遍历到的节点头插法插到新的链表中。这个方法简单,就不展示代码了

总结

这篇文章分享了经典的算法--反转链表,文中提供了三种代码编写方式,都不难,代码注释和解释也都很清晰,方便大家理解

你觉得这篇文章怎么样?喜欢就点赞+关注吧

相关推荐
pianmian12 分钟前
python数据结构基础(7)
数据结构·算法
cs_dn_Jie2 小时前
钉钉 H5 微应用 手机端调试
前端·javascript·vue.js·vue·钉钉
好奇龙猫2 小时前
【学习AI-相关路程-mnist手写数字分类-win-硬件:windows-自我学习AI-实验步骤-全连接神经网络(BPnetwork)-操作流程(3) 】
人工智能·算法
开心工作室_kaic2 小时前
ssm068海鲜自助餐厅系统+vue(论文+源码)_kaic
前端·javascript·vue.js
有梦想的刺儿2 小时前
webWorker基本用法
前端·javascript·vue.js
sp_fyf_20243 小时前
计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-11-01
人工智能·深度学习·神经网络·算法·机器学习·语言模型·数据挖掘
ChoSeitaku3 小时前
链表交集相关算法题|AB链表公共元素生成链表C|AB链表交集存放于A|连续子序列|相交链表求交点位置(C)
数据结构·考研·链表
偷心编程3 小时前
双向链表专题
数据结构
香菜大丸3 小时前
链表的归并排序
数据结构·算法·链表
jrrz08283 小时前
LeetCode 热题100(七)【链表】(1)
数据结构·c++·算法·leetcode·链表