【前端算法】定义一个JS函数,反转单向链表

简介: 介绍链表与数组的区别,以及它们之间的联系

链表

  • 链表是一种物理结构(非逻辑结构),类似数组
  • 数组需要一段连续的内存空间,而链表试试零散的
  • 链表节点的数据结构{value, next?, prev?}

链表 VS 数组

  • 都是有序结构
  • 链表:查询慢 O(n), 新增和删除快O(1)
  • 数组:查询快O(1),新增和删除慢O(n)

创建链表代码示例

interface ILinkNode {
  value: number
  next?: ILinkNode
}

function createLinkNode (arr: number[]): ILinkNode {
  const len = arr.length
  if (len === 0) throw Error('this is a empty array');

  let curNode:ILinkNode = {
    value: arr[len-1]
  }

  if (len === 1) return curNode;

  for(let i = len -2; i >= 0; i--){
    curNode = {
      value: arr[i],
      next: curNode
    }
  }

  return curNode
}

解题思路

  • 反转,即节点next指向前一个节点
  • 但这很容易造成nextNode 的丢失
  • 需要三个指针 prevNode curNode nextNode

反转单向链表代码示例

function reverseLinkNode (linkNode:ILinkNode):ILinkNode {
  // 定义3个指针
  let prevNode: ILinkNode | undefined
  let curNode: ILinkNode | undefined
  let nextNode: ILinkNode | undefined = linkNode

  // 以nextNode为主,遍历链表
  while (nextNode) {
    // 删除第一个元素的next,防止循环引用
    if(curNode && !prevNode) {
     delete curNode.next
    }

    // 反转指针
    if (curNode && prevNode) {
      curNode.next = prevNode
    }

    // 整体向后移动
    prevNode = curNode
    curNode = nextNode
    nextNode = (nextNode as ILinkNode)?.next
  }
  // 最后一个补充:当nextNode为空时,curNode没有next时,设置next指向prevNode
  curNode!.next = prevNode

return curNode!
}

功能测试

const arr = [100,200,300]
const link = createLinkNode(arr)
console.log(link)
/*
{
  "value": 100,
  "next": {
    "value": 200,
    "next": {
      "value": 300
    }
  }
}
*/
console.log(reverseLinkNode(link))
/*
{
  "value": 300,
  "next": {
    "value": 200,
    "next": {
      "value": 100
    }
  }
} 
*/

能够跟据数组创建一个完整的单向链表,且反转单向链表功能正常。

单元测试

describe('反转链表', () => {
    it('单个元素', () => {
        const node = { value: 100}
        const node1:ILinkNode = reverseLinkNode(node)
        expect(node1).toEqual({ value: 100})
    })
    
    it('多个元素', () => {
        const arr = [100, 200, 300]
        const node:ILinkNode = createLinkNode(arr)
        const node1:ILinkNode = reverseLinkNode(node)
        expcet(node1).toEqual({
            value: 300,
            next: {
                value: 200,
                next: {
                    value: 100
                }
            }
        })
    })
})
相关文章
|
7月前
|
算法 机器人 定位技术
【VRPTW】基于matlab秃鹰算法BES求解带时间窗的骑手外卖配送路径规划问题(目标函数:最优路径成本 含服务客户数量 服务时间 载量 路径长度)(Matlab代码实现)
【VRPTW】基于matlab秃鹰算法BES求解带时间窗的骑手外卖配送路径规划问题(目标函数:最优路径成本 含服务客户数量 服务时间 载量 路径长度)(Matlab代码实现)
233 0
|
6月前
|
机器学习/深度学习 传感器 算法
基于matlab瞬态三角哈里斯鹰算法TTHHO多无人机协同集群避障路径规划(目标函数:最低成本:路径、高度、威胁、转角)(Matlab代码实现)
基于matlab瞬态三角哈里斯鹰算法TTHHO多无人机协同集群避障路径规划(目标函数:最低成本:路径、高度、威胁、转角)(Matlab代码实现)
251 1
|
7月前
|
机器学习/深度学习 算法 数据挖掘
【配送路径规划】基于螳螂虾算法MShOA求解带时间窗的骑手外卖配送路径规划问题(目标函数:最优路径成本 含服务客户数量 服务时间 载量 路径长度)研究(Matlab代码实现)
【配送路径规划】基于螳螂虾算法MShOA求解带时间窗的骑手外卖配送路径规划问题(目标函数:最优路径成本 含服务客户数量 服务时间 载量 路径长度)研究(Matlab代码实现)
290 0
|
7月前
|
算法 Python
【配送路径规划】基于遗传算法求解带时间窗的电动汽车配送路径规划(目标函数:最小成本;约束条件:续驶里程、额定载重量、数量、起始点)研究(Matlab代码实现)
【配送路径规划】基于遗传算法求解带时间窗的电动汽车配送路径规划(目标函数:最小成本;约束条件:续驶里程、额定载重量、数量、起始点)研究(Matlab代码实现)
258 0
|
11月前
|
前端开发 JavaScript 数据可视化
58K star!这个让网页动起来的JS库,前端工程师直呼真香!
Anime.js 是一款轻量级但功能强大的JavaScript动画引擎,它能够以最简单的方式为网页元素添加令人惊艳的动效。这个项目在GitHub上已经获得58,000+星标,被广泛应用于电商页面、数据可视化、游戏开发等场景。
433 8
|
11月前
|
JavaScript 前端开发 容器
|
11月前
|
JavaScript 前端开发
|
11月前
|
存储 JavaScript 前端开发
|
11月前
|
移动开发 JavaScript 前端开发
|
11月前
|
存储 JavaScript 前端开发