JavaScript数据结构之链表各种操作详解

yizhihongxing

JavaScript数据结构之链表各种操作详解

链表是一种常见的数据结构,常用于实现栈和队列等数据结构。链表与数组不同,链表是一种动态数据结构,可以方便地插入和删除数据。下面将详细讲解JavaScript中链表的各种操作。

链表的基本结构

链表由一个个节点组成,每个节点包含两个部分:数据域和指针域。数据域存储节点的数据,指针域存储下一个节点的地址。

下面是一个节点的定义:

class Node {
  constructor(data) {
    this.data = data;
    this.next = null;
  }
}

其中,data表示节点的数据,next指向下一个节点的地址。如果nextnull则表示链表的末尾。

整个链表可以用一个头节点来表示。头节点不包含数据,只包含指针,指向第一个节点。

下面是一个头节点的定义:

class LinkedList {
  constructor() {
    this.head = null;
  }
}

链表的各种操作

在链表末尾添加节点

在链表末尾添加节点是一种常见的操作。实现方法如下:

LinkedList.prototype.append = function(data) {
  let node = new Node(data);
  if (this.head === null) {
    this.head = node;
  } else {
    let current = this.head;
    while (current.next !== null) {
      current = current.next;
    }
    current.next = node;
  }
};

上述代码中,如果链表为空,则直接将新节点设置为头节点。否则,遍历链表,找到链表末尾,将新节点添加到末尾。

在链表头部添加节点

在链表头部添加节点也常常用到。可以通过如下方式实现:

LinkedList.prototype.prepend = function(data) {
  let node = new Node(data);
  node.next = this.head;
  this.head = node;
};

在添加一个节点时,先将新节点的next指向当前头节点,然后将新节点设置为头节点。

在指定位置插入节点

如果要在链表的指定位置插入数据,可以通过如下方式实现:

LinkedList.prototype.insert = function(data, position) {
  let node = new Node(data);
  if (position === 0) {
    this.prepend(data);
  } else {
    let current = this.head;
    let index = 0;
    while (index < position - 1) {
      current = current.next;
      index++;
    }
    node.next = current.next;
    current.next = node;
  }
};

如果需要在头部插入,可以调用prepend方法。否则,需要遍历链表,找到插入位置,然后将新节点插入到链表中。

遍历链表

遍历链表可以通过如下方式实现:

LinkedList.prototype.traverse = function() {
  let current = this.head;
  while (current !== null) {
    console.log(current.data);
    current = current.next;
  }
};

这个方法通过循环,从头节点开始遍历整个链表,并输出每个节点的数据。

查找节点

如果需要查找链表中的某个节点,可以通过如下方式实现:

LinkedList.prototype.indexOf = function(data) {
  let current = this.head;
  let index = 0;
  while (current !== null) {
    if (current.data === data) {
      return index;
    }
    current = current.next;
    index++;
  }
  return -1;
};

这个方法遍历整个链表,查找某个节点的数据是否等于指定的数据。如果找到则返回节点的索引,否则返回-1。

删除节点

删除节点也是链表中的一种常见操作,可以通过如下方式实现:

LinkedList.prototype.delete = function(data) {
  if (this.head === null) {
    return;
  }
  if (this.head.data === data) {
    this.head = this.head.next;
    return;
  }
  let current = this.head;
  while (current.next !== null) {
    if (current.next.data === data) {
      current.next = current.next.next;
      return;
    }
    current = current.next;
  }
};

如果需要删除头节点,直接将头节点指向下一个节点即可。否则需要遍历链表,找到要删除的节点,然后删除它。

示例说明

示例1:用链表实现栈

链表可以方便地实现栈和队列等数据结构。下面示范通过链表实现栈的方式:

class Stack {
  constructor() {
    this.list = new LinkedList();
  }

  push(data) {
    this.list.prepend(data);
  }

  pop() {
    let head = this.list.head;
    if (head === null) {
      return null;
    }
    this.list.head = head.next;
    return head.data;
  }

  isEmpty() {
    return this.list.head === null;
  }

  size() {
    let current = this.list.head;
    let count = 0;
    while (current !== null) {
      count++;
      current = current.next;
    }
    return count;
  }
}

可以看到,这个栈类内部使用链表来存储数据。push方法将新的元素添加到链表头部,pop方法将链表的头节点弹出,并返回节点的数据。isEmpty方法用来判断栈是否为空,size方法返回栈的元素个数。

示例2:通过链表实现一元多项式

链表还可以用来实现一元多项式。一元多项式可以表示为:

a0 + a1x + a2x² + ... + anxⁿ

这个式子中,a0 ~ an表示系数,x表示未知数,n表示项数。

下面是一个用链表实现一元多项式的示例:

class Node {
  constructor(coef, exp) {
    this.coef = coef;
    this.exp = exp;
    this.next = null;
  }
}

class Polynomial {
  constructor() {
    this.head = null;
  }

  append(coef, exp) {
    let node = new Node(coef, exp);
    if (this.head === null) {
      this.head = node;
    } else {
      let current = this.head;
      while (current.next !== null) {
        current = current.next;
      }
      current.next = node;
    }
  }

  add(p) {
    let result = new Polynomial();
    let p1 = this.head;
    let p2 = p.head;
    while (p1 !== null && p2 !== null) {
      if (p1.exp === p2.exp) {
        result.append(p1.coef + p2.coef, p1.exp);
        p1 = p1.next;
        p2 = p2.next;
      } else if (p1.exp > p2.exp) {
        result.append(p1.coef, p1.exp);
        p1 = p1.next;
      } else {
        result.append(p2.coef, p2.exp);
        p2 = p2.next;
      }
    }
    while (p1 !== null) {
      result.append(p1.coef, p1.exp);
      p1 = p1.next;
    }
    while (p2 !== null) {
      result.append(p2.coef, p2.exp);
      p2 = p2.next;
    }
    return result;
  }

  toString() {
    let current = this.head;
    let str = '';
    while (current !== null) {
      if (current.coef !== 0) {
        str += current.coef;
        if (current.exp !== 0) {
          str += 'x^' + current.exp;
        }
        if (current.next !== null && current.next.coef > 0) {
          str += '+';
        }
      }
      current = current.next;
    }
    return str;
  }
}

这个代码中,每个节点包含系数coef和指数exp,通过链表可以存储多个节点。append方法用来向多项式添加新的项,add方法用来将两个多项式相加,toString方法将多项式转化为字符串输出。

以上就是链表的各种操作详解,通过这些方法,可以方便地实现更多的数据结构和算法。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JavaScript数据结构之链表各种操作详解 - Python技术站

(0)
上一篇 2023年6月8日
下一篇 2023年6月8日

相关文章

  • NodeJs 文件系统操作模块fs使用方法详解

    NodeJs 文件系统操作模块fs使用方法详解 Node.js作为一款基于JavaScript的服务端脚本运行环境,拥有着强大的文件系统操作模块fs。fs模块提供了许多API以进行文件读、写等操作,本文将详细讲解fs模块的使用方法。 fs模块的引入 在使用fs模块之前,需要先进行引入。可以使用以下代码实现: const fs = require(‘fs’);…

    node js 2023年6月8日
    00
  • Ajax中post方法直接返回以0开头数字出错问题分析

    当我们使用Ajax中的post方法发起请求时,有时可能会出现返回值以0开头数字出错的情况。这个问题的原因是在Ajax里面,返回以0开头的数字会被解析成八进制数,而不是十进制数,因此造成了解析错误。 解决这个问题的方法很简单,一种方法是将返回值转换成字符串类型,另一种方法是在服务器端设置返回头,让其返回值以JSON格式输出。 下面,我将分别演示这两种解决方法:…

    node js 2023年6月8日
    00
  • 在NodeJs中使用node-schedule增加定时器任务的方法

    在Node.js中,可以使用node-schedule包来创建定时器,该包可以用于执行重复的定时任务或者单次执行的任务。下面是使用node-schedule包来增加定时器任务的方法: 1. 安装node-schedule包 可以使用npm命令来安装node-schedule包: npm install node-schedule 2. 引入node-sche…

    node js 2023年6月8日
    00
  • Node.js 实现远程桌面监控的方法步骤

    针对“Node.js 实现远程桌面监控的方法步骤”这个主题,我将根据以下步骤给出详细的攻略: 确定项目需求,选择合适的开发框架和技术栈。 搭建基础环境,如安装Node.js和npm。 实现远程桌面监控的功能,可以考虑使用第三方工具或者自行封装。 搭建前端页面,结合WebSocket技术实现实时监控。 部署,将应用程序上传至服务器,并配置好相关环境。 下面我将…

    node js 2023年6月8日
    00
  • 详解autojs的nodejs编写UI技巧示例

    标题:详解Auto.js的Node.js编写UI技巧示例 Auto.js是一款Android平台上的JavaScript脚本引擎。除了支持JavaScript语言特性外,它还为开发者提供了编写UI界面的API,使得开发者可以通过JavaScript语言编写Android应用程序。本文将为大家介绍Auto.js的Node.js编写UI技巧,并给出两条示例说明。…

    node js 2023年6月8日
    00
  • Vue使用Echarts实现数据可视化的方法详解

    下面我将详细讲解“Vue使用Echarts实现数据可视化的方法详解”的攻略,包含以下内容: 概述 本攻略主要介绍如何在Vue项目中使用Echarts进行数据可视化。Echarts是一个非常强大的数据可视化库,提供了各种不同类型的图表(例如折线图、柱状图、饼图、地图等)以及丰富的交互功能。 1. 安装Echarts 首先需要在项目中安装Echarts。可以使用…

    node js 2023年6月8日
    00
  • 浅谈Nodejs中的作用域问题

    浅谈Node.js中的作用域问题 作用域是编程中一个非常重要的概念,它定义了变量和函数的可访问性。Node.js在处理作用域问题时也有自己的特点。 作用域 在Node.js中,作用域分为全局作用域和函数作用域两种。 全局作用域中定义的变量可以在整个程序中被访问到,例如: var a = 10; function test() { console.log(a)…

    node js 2023年6月8日
    00
  • 浅谈JavaScript工具链不完全指南

    首先,我们需要明确一下什么是JavaScript工具链。JavaScript工具链是指开发者使用的工具集合,主要用于提高开发效率和代码质量。常见的JavaScript工具链包括构建工具、测试工具、代码质量检测工具和打包工具等。 本文旨在浅谈JavaScript工具链的不完全指南,介绍一些常用的JavaScript开发工具以及用法。 一、构建工具 构建工具主要…

    node js 2023年6月8日
    00
合作推广
合作推广
分享本页
返回顶部