JavaScript数据结构链表知识详解

yizhihongxing

JavaScript数据结构链表知识详解

什么是链表

链表是一种线性结构,相比于数组,它不需要一块连续的内存空间,而是通过指针将一组零散的内存块串联起来使用。链表只保持一个指向链表中第一个节点的引用,每个节点则有指向下一个节点的指针。

链表的实现

链表的实现方式有很多种,下面介绍一种简单的单向链表实现方式,其中每个节点包含一个value属性和一个next属性,next属性指向下一个节点(没有则为null)。

class ListNode {
  constructor(value) {
    this.value = value;
    this.next = null;
  }
}

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

  append(value) {
    const node = new ListNode(value);
    if (this.head === null) {
      // 链表为空,添加第一个节点
      this.head = node;
    } else {
      // 链表不为空,遍历到最后一个节点,添加新的节点
      let current = this.head;
      while (current.next !== null) {
        current = current.next;
      }
      current.next = node;
    }
    this.length++;
  }

  insert(value, position) {
    if (position < 0 || position > this.length) {
      // 如果指定的位置小于0或大于链表长度,不能插入
      return false;
    }
    const node = new ListNode(value);
    if (position === 0) {
      // 添加到链表头部
      node.next = this.head;
      this.head = node;
    } else {
      // 找到要插入位置的前一个节点,插入节点
      let index = 0;
      let current = this.head;
      let previous = null;
      while (index < position) {
        previous = current;
        current = current.next;
        index++;
      }
      node.next = current;
      previous.next = node;
    }
    this.length++;
    return true;
  }

  remove(position) {
    if (position < 0 || position >= this.length) {
      // 如果指定的位置小于0或大于等于链表长度,不能删除
      return false;
    }
    if (position === 0) {
      // 删除链表头部节点
      this.head = this.head.next;
    } else {
      // 找到要删除位置的前一个节点,删除节点
      let index = 0;
      let current = this.head;
      let previous = null;
      while (index < position) {
        previous = current;
        current = current.next;
        index++;
      }
      previous.next = current.next;
    }
    this.length--;
    return true;
  }

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

  toString() {
    let listString = '';
    let current = this.head;
    while (current !== null) {
      listString += current.value + ' ';
      current = current.next;
    }
    return listString;
  }
}

链表的应用

链表可以用来解决很多问题,比如:

  1. 链表可以用来实现栈和队列:栈和队列都是顺序访问的数据结构,用数组实现时需要考虑数组的大小问题,而用链表实现则没有这个问题。
  2. 链表可以用来实现哈希表:哈希表需要快速插入、删除和查找元素,使用链表可以实现这个目标。
  3. 链表可以用来实现LRU缓存算法:LRU缓存算法需要快速插入、删除和查找元素,使用链表实现可以达到O(1)的时间复杂度。

下面举两个链表的应用示例:

示例1:用链表实现栈

栈是一种后进先出(LIFO)的数据结构,可以用链表来实现。栈的基本操作包括push、pop和peek。

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

  push(value) {
    this.list.append(value);
  }

  pop() {
    if (this.list.length === 0) {
      return null;
    }
    const index = this.list.length - 1;
    const value = this.list.get(index);
    this.list.remove(index);
    return value;
  }

  peek() {
    if (this.list.length === 0) {
      return null;
    }
    const index = this.list.length - 1;
    return this.list.get(index);
  }

  toString() {
    return this.list.toString();
  }
}

示例2:用链表实现LRU缓存算法

LRU缓存算法(Least Recently Used)是一种常用的缓存淘汰算法,它基于这样一个假设:如果数据最近被访问过,那么将来被访问的几率也很高。根据这个原理,LRU缓存算法将最近最少使用(Least Recently Used)的数据淘汰掉。

class LRUCache {
  constructor(capacity) {
    this.capacity = capacity;
    this.list = new LinkedList();
    this.map = new Map();
  }

  get(key) {
    if (!this.map.has(key)) {
      return null;
    }
    const node = this.map.get(key);
    // 移动到链表头部
    this.list.removeNode(node);
    this.list.addNodeToFront(node);
    return node.value.value;
  }

  put(key, value) {
    if (this.map.has(key)) {
      // 如果已存在,更新值,并移动到链表头部
      const node = this.map.get(key);
      node.value.value = value;
      this.list.removeNode(node);
      this.list.addNodeToFront(node);
    } else {
      // 如果不存在,添加到链表头部
      const node = new ListNode({ key, value });
      this.list.addNodeToFront(node);
      this.map.set(key, node);
      // 检查容量是否超出限制
      if (this.map.size > this.capacity) {
        // 如果超出限制,删除链表尾部节点和map中的对应项
        const nodeToDelete = this.list.tail;
        this.list.removeNode(nodeToDelete);
        this.map.delete(nodeToDelete.value.key);
      }
    }
  }

  toString() {
    return this.list.toString();
  }
}

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

(0)
上一篇 2023年5月17日
下一篇 2023年5月17日

相关文章

  • 图计算引擎分析–GridGraph

    作者:京东科技 李永萍 GridGraph:Large-Scale Graph Processing on a Single Machine Using 2-Level Hierarchical Partitioning 图计算框架 图计算系统按照计算方式划分可分为:单机内存图处理系统,单机核外图处理系统,分布式内存图处理系统,分布式核外图处理系统。本文将详…

    算法与数据结构 2023年4月20日
    00
  • Java性能优化之数据结构实例代码

    Java性能优化之数据结构实例代码攻略 本篇攻略主要介绍Java性能优化之数据结构实例代码的相关内容,包括数据结构的优化方法以及示例代码等。我们使用以下两个示例来说明性能优化的过程和方法。 示例1:字符串拼接 在Java中字符串拼接通常使用”+=”方式,但是在循环中频繁地使用该操作会导致性能问题。这时可以使用StringBuilder类的append()方法…

    数据结构 2023年5月17日
    00
  • 稀疏数组

    引入 当在网页上下棋类游戏时,玩到中途想要离开,但是我们需要保存进度,方便下次继续 我们应该怎么实现 ? 以围棋举例 使用二维数组将棋盘记下 ,如 0 为 没有棋子 ,1 为 黑子 , 2为白子 但是没有棋子的地方都为 0 ,整个二维数组充斥着大量的无效数据 0 我们需要想一个办法来 优化存储的方式 基本介绍 当一个数组中大部分元素是同一个值时,我们可以使用…

    算法与数据结构 2023年4月19日
    00
  • Java 数据结构线性表之顺序存储详解原理

    Java 数据结构线性表之顺序存储详解原理 一、什么是线性表 线性表(Linear List)指的是同一类数据元素的集合,而且这些元素之间是有序的。线性表具有两个显著的特点:第一,有且仅有一个被称为“第一个”的数据元素;第二,有且仅有一个被称为“最后一个”的数据元素;此外,除第一个和最后一个数据元素外,其它数据元素均有且仅有一个直接前驱和一个直接后继。 二、…

    数据结构 2023年5月17日
    00
  • golang优先级队列的实现全过程

    下面是关于”golang优先级队列的实现全过程”的详细讲解。 什么是优先级队列? 优先级队列是一种常用的数据结构,它可以帮我们按照一定规则(即优先级)将元素按照大小排序,并支持快速插入、删除和查询最大或最小的元素等操作。我们可以将优先级队列想象成一个具有优先级的、自动排序的队列,其中优先级高的元素(比如数字大的元素)排在前面,优先级低的元素(比如数字小的元素…

    数据结构 2023年5月17日
    00
  • qqwry.dat的数据结构图文解释第1/2页

    “qqwry.dat的数据结构图文解释第1/2页”的完整攻略 1. 什么是qqwry.dat? qqwry.dat是一个IP地址库,包含了全球的IP地址信息,例如:所属国家、所属地区、详细地址等信息。在大多数系统或应用程序中,都可以使用qqwry.dat来查询IP地址信息。 2. qqwry.dat的数据结构 qqwry.dat的数据结构可以通过两个文件来描…

    数据结构 2023年5月16日
    00
  • 一行python实现树形结构的方法

    想要一行Python实现树形结构,我们需要使用Python的字典数据类型来完成任务。下面是详细的操作步骤: 创建树形结构字典 我们可以用嵌套字典来表示树形结构,我们需要选择其中一个节点作为根节点,并以键值对的形式保存其子节点。最终,我们将根节点作为整个字典的返回值。下面是实现代码: tree = lambda: defaultdict(tree) 插入节点 …

    数据结构 2023年5月17日
    00
  • Java数据结构二叉树难点解析

    Java数据结构二叉树难点解析 什么是二叉树 二叉树是一种非常常见的数据结构,它具有以下特点: 每个节点都最多有两个子节点。 左子节点的值小于等于父节点的值,右子节点的值大于等于父节点的值。 二叉树可以用递归的方式实现,如下所示: class TreeNode { int val; TreeNode left; TreeNode right; TreeNod…

    数据结构 2023年5月17日
    00
合作推广
合作推广
分享本页
返回顶部