手把手教你用JavaScript征服链表算法!

45 阅读2分钟

📋 文章大纲

一、开篇:为什么前端要学链表?

  • 数组的痛:那些年我们一起搬过的数据
    • splice(2, 0, 99)三个参数:从哪里开始、删除几个元素、插入什么值
    • 你以为直接插入?大错特错!JS引擎先将索引2后面的元素全部往后挪一位,然后再把值加入当前数组,时间复杂度为O(arr.length-index)
// 1.向数组插入值
const array = [1, 2, 3, 4, 5];
array.splice(2, 0, 99);
console.log(array); // 输出:[1, 2, 99, 3, 4, 5]
  • 链表的优雅:像火车车厢一样自由连接
    • 链表要插入或删除一个值,直接将当前车厢和下一节车厢分开,然后加入新的车厢,再将新旧车厢相连,时间复杂度O(1),极大优化性能
    • 请看图:

链表插入示意图

  • 现实应用:React Fiber、Vue3响应式、浏览器历史记录

二、初识链表:数据结构界的"贪吃蛇"

  • 从数组到链表:思维转换
    • 数组通过下标访问数据,链表通过指针遍历节点
const array = [1, 2, 3, 4, 5];
array.splice(2, 0, 99);
console.log(array); // 输出:[1, 2, 99, 3, 4, 5]
console.log(array[2]); // 输出:99
  • 节点概念:数据 + 指针 = 无限可能

    • 链表由节点通过指针连接而成
    • 访问数据需要从头节点开始,通过指针逐个遍历
    • 编程中常用:head代表头节点,head.next表示下一节点,value访问节点值
  • 可视化理解:图示说明

链表结构示意图

三、算法解析:LeetCode精选

3.1 简单题:反转链表(206题)

反转链表示意图

  • 反转链表的核心思路:改变每个节点的指向方向
/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} head
 * @return {ListNode}
 */
var reverseList = function(head) {
    let prev = null;
    let curr = head;
    while (curr) {
        const next = curr.next; // 保存下一个节点
        curr.next = prev;       // 反转当前节点的指向
        prev = curr;            // prev向前移动
        curr = next;            // curr向前移动
    }
    return prev; // 返回新的头节点
};

执行过程详解

  • 第一次循环

第一次循环

  • 第二次循环

第二次循环

  • 继续执行直到完成

后续循环

  • 最终返回prev,得到反转后的链表

以上就是今天的算法学习了,下期见!!!