JavaScript数据结构链表知识详解

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日

相关文章

  • C++如何实现BitMap数据结构

    下面我将详细讲解C++如何实现BitMap数据结构的完整攻略,包含以下几个方面: 什么是BitMap数据结构 如何使用C++实现BitMap数据结构 BitMap数据结构的应用示例说明 1. 什么是BitMap数据结构 BitMap数据结构也叫位图,是一种非常简单而高效的数据结构,它主要是用来对大量数字进行存储和操作的。所谓BitMap,就是将一个数字序列通…

    数据结构 2023年5月17日
    00
  • 栈(Stack)

    概述 栈就是一种 只允许在表尾进行插入和删除操作 的 线性表 栈的特点 先进后出 ,在表尾进行插入和删除操作 数组实现栈 crown crown:使用bottom来确定栈顶所在数组的下标,默认为 -1 空栈 当空栈时 ,crown = -1 栈是否为空 当 crown = -1 时 ,栈为空 ,不能 遍历 ,出栈 , 获取栈顶元素 栈是否已满 当 crown…

    算法与数据结构 2023年4月19日
    00
  • C语言数据结构之复杂链表的拷贝

    C语言数据结构之复杂链表的拷贝 什么是复杂链表 在了解如何拷贝复杂链表之前,首先需要知道什么是复杂链表。复杂链表是由多个节点组成的链表,每个节点除了包含普通链表节点的值和指向下一个节点的指针外,还包含一个指向链表中的任意一个节点的指针。因此,每个节点有两个指针:一个指向下一个节点,一个指向任意一个节点。 复杂链表示意图如下: +—+ +—+ +—…

    数据结构 2023年5月17日
    00
  • 一步步带你学习设计MySQL索引数据结构

    一步步带你学习设计MySQL索引数据结构 索引原理 在MySQL中,索引是一种数据结构,用于快速查找表中的记录。在一张表中,可以使用不同的列来创建索引,索引可以大大提高查询效率,减少扫描行数,加快数据查询速度。 索引的实现一般使用的是B树和B+树这两种数据结构,因为它们都具有良好的平衡性,可以快速查找,插入和删除。 如何设计MySQL索引 确认需要优化的查询…

    数据结构 2023年5月17日
    00
  • C++数据结构关于栈迷宫求解示例

    C++数据结构关于栈迷宫求解示例攻略 在本篇攻略中,我们将使用C++数据结构中的栈来解决迷宫问题,具体将通过两个示例来详细讲解该方法。首先介绍一下栈的概念。 栈的概念 栈是一种“后入先出”的数据结构,即最后压入栈中的元素会首先被弹出,而最早压入栈中的元素会最后被弹出。栈的基本操作有入栈(push)、出栈(pop)、判断是否为空以及读取栈顶元素等。 迷宫问题 …

    数据结构 2023年5月17日
    00
  • C语言线性表的链式表示及实现详解

    C语言线性表的链式表示及实现详解 什么是线性表 线性表是一种在计算机科学中常见的数据结构,它由一组连接在一起的元素组成,每个元素都包含前后指针以指向相邻的元素,从而构成一个连续的线性序列。线性表可以用来存储和处理一般数据集合。 链式存储结构 线性表的链式存储结构是由若干个结构体组成的链表,每个结构体都称为一个节点。每个节点包含两个字段:一个数据域用来存放数据…

    数据结构 2023年5月17日
    00
  • java编程队列数据结构代码示例

    下面是“Java编程队列数据结构代码示例”的完整攻略。 什么是队列 队列是一种有序的数据结构,特点是先进先出(FIFO)。队列中不管是插入操作还是删除操作,都是在队列的两端进行的,插入操作在队列的尾部进行,删除操作在队列的头部进行。队列的一个重要用途是在计算机的操作系统中,实现进程和所有需要等待资源的实体之间的交互。 队列的实现 队列数据结构可以采用数组或链…

    数据结构 2023年5月17日
    00
  • Go语言数据结构之二叉树必会知识点总结

    Go语言数据结构之二叉树必会知识点总结 二叉树是一种非常重要的数据结构,它被广泛应用于算法、数据处理等领域。在Go语言中,使用二叉树可以实现很多高级数据结构和算法。本文将为大家介绍二叉树相关的基本知识和操作,以及如何利用Go语言实现二叉树。 什么是二叉树? 二叉树是一种树形结构,由一个根节点和两个子树组成。它的每个节点最多有两个子节点,称为左子节点和右子节点…

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