【前端算法】定义一个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
                }
            }
        })
    })
})
相关文章
|
12天前
|
JavaScript 前端开发 Java
[JS]同事:这次就算了,下班回去赶紧补补内置函数,再犯肯定被主管骂
本文介绍了JavaScript中常用的函数和方法,包括通用函数、Global对象函数以及数组相关函数。详细列出了每个函数的参数、返回值及使用说明,并提供了示例代码。文章强调了函数的学习应结合源码和实践,适合JavaScript初学者和进阶开发者参考。
25 2
[JS]同事:这次就算了,下班回去赶紧补补内置函数,再犯肯定被主管骂
|
11天前
|
前端开发 JavaScript 开发者
除了 Generator 函数,还有哪些 JavaScript 异步编程解决方案?
【10月更文挑战第30天】开发者可以根据具体的项目情况选择合适的方式来处理异步操作,以实现高效、可读和易于维护的代码。
|
17天前
|
算法 安全 搜索推荐
2024重生之回溯数据结构与算法系列学习之单双链表精题详解(9)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构王道第2.3章之IKUN和I原达人之数据结构与算法系列学习x单双链表精题详解、数据结构、C++、排序算法、java、动态规划你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
|
17天前
|
存储 Web App开发 算法
2024重生之回溯数据结构与算法系列学习之单双链表【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构之单双链表按位、值查找;[前后]插入;删除指定节点;求表长、静态链表等代码及具体思路详解步骤;举例说明、注意点及常见报错问题所对应的解决方法
|
25天前
|
JavaScript 前端开发
JavaScript 函数语法
JavaScript 函数是使用 `function` 关键词定义的代码块,可在调用时执行特定任务。函数可以无参或带参,参数用于传递值并在函数内部使用。函数调用可在事件触发时进行,如用户点击按钮。JavaScript 对大小写敏感,函数名和关键词必须严格匹配。示例中展示了如何通过不同参数调用函数以生成不同的输出。
|
27天前
|
存储 JavaScript 前端开发
JS函数提升 变量提升
【10月更文挑战第6天】函数提升和变量提升是 JavaScript 语言的重要特性,但它们也可能带来一些困惑和潜在的问题。通过深入理解和掌握它们的原理和表现,开发者可以更好地编写和维护 JavaScript 代码,避免因不了解这些机制而导致的错误和不一致。同时,不断提高对执行上下文等相关概念的认识,将有助于提升对 JavaScript 语言的整体理解和运用能力。
|
1月前
|
前端开发 JavaScript
前端:实现一个 sleep 函数
在前端开发中,实现一个 `sleep` 函数可以用来暂停代码执行,模拟延迟效果,常用于测试或控制异步操作的节奏。该函数通常基于 `Promise` 和 `setTimeout` 实现,简单易用。
|
1月前
|
存储 缓存 算法
经典算法之链表篇(三)
经典算法之链表篇(三)
|
30天前
|
存储 JavaScript 前端开发
JavaScript数据类型全解:编写通用函数,精准判断各种数据类型
JavaScript数据类型全解:编写通用函数,精准判断各种数据类型
18 0
|
30天前
|
移动开发 算法 前端开发
前端常用算法全解:特征梳理、复杂度比较、分类解读与示例展示
前端常用算法全解:特征梳理、复杂度比较、分类解读与示例展示
21 0