当前位置: 首页 > article >正文

循环链表 - 使用JavaScript封装

我学习了一生,现在我还在学习,而将来,只要我还有精力,我还要学习下去。” —— 别林斯基

目录

  • 循环链表:
  • 封装循环链表 - js:
  • 应用场景:

循环链表:

循环链表和链表之间唯一的区别在于,最后一个元素指向下一个元素的指针不是引用undefined,而是指向第一个元素 head。
在这里插入图片描述
图为千锋教育所截,侵权联系删除。

封装循环链表 - js:

这里封装的循环链表还是继承了之前写的单链表。。。

<script>
  class Node {
    constructor(element) {
      this.element = element;
      this.next = null;
    }
  }

  class LinkedList {
    // #
    constructor() {
      this.count = 0;
      this.head = null;
    }

    // push 添加一个节点
    push (element) {
      const node = new Node(element);

      // header是空
      if (this.head === null) {
        this.head = node;
      } else {
        let current = this.head;
        while (current.next !== null) {
          current = current.next;
        }
        current.next = node;
      }
      this.count++;
    }

    // 指定位置删除 传入索引
    removeAt (index) {
      if (index >= 0 && index < this.count) {
        let current = this.head;
        if (index == 0) {
          this.head = this.head.next;
        } else {
          let previous;
          for (let i = 0; i < index; i++) {
            previous = current;
            current = current.next;
          }
          previous.next = current.next;
        }
        this.count--;
        return current.element;
      }
      return;
    }
    // 指定位置删除-方法二利用getNodeAt(index) 传入索引
    removeAt2 (index) {
      if (index >= 0 && index < this.count) {
        let current = this.head;
        if (index == 0) {
          this.head = this.head.next;
        } else {
          let previous = this.getNodeAt(index - 1);
          current = previous.next;
          previous.next = current.next;
        }
        this.count--;
        return current.element;
      }
      return;
    }

    // 根据索引获得节点node
    getNodeAt (index) {
      if (index >= 0 && index < this.count) {
        let node = this.head;

        for (let i = 0; i < index; i++) {
          node = node.next;
        }
        return node;
      }
      return;
    }

    // 判断是否相等
    equalFn (a, b) {
      // 暴力写法:
      // 也有缺陷 JSON.stringify({a:1,b:2}) !== JSON.stringify({b:2,a:1})
      return JSON.stringify(a) === JSON.stringify(b);
      // 可以使用第三方库
    }

    // 根据元素返回索引
    indexOf (element) {
      let current = this.head;
      for (let i = 0; i < this.count; i++) {
        if (this.equalFn(current.element, element)) {
          return i;
        }
        current = current.next;
      }
    }

    // 直接根据值删除
    remove (element) {
      // 根据数据返回索引的方法
      const index = this.indexOf(element);
      return this.removeAt(index);
    }

    // 指定位置插入内容
    insert (element, index) {
      if (index >= 0 && index <= this.count) {
        const node = new Node(element);
        if (index == 0) {
          const current = this.head;
          node.next = current;
          this.head = node;
        } else {
          const previous = this.getNodeAt(index - 1);
          const current = previous.next;
          previous.next = node;
          node.next = current;
        }
        this.count++;
        return true;
      }
      return false;
    }

    // 判断是否为空
    isEmpty () {
      return this.size() === 0;
    }
    // 判断长度
    size () {
      return this.count;
    }

    // 返回链头
    getHead () {
      return this.head;
    }
  }

</script>
<script>
  class CirularLinkedList extends LinkedList {
    constructor() {
      super()
    }
    push (element) {
      const node = new Node(element);
      let current;
      if (this.head === null) {
        this.head = node;
      } else {
        current = this.getNodeAt(this.size() - 1);
        current.next = node;
      }
      node.next = this.head;
      this.count++;
    }
    insert (element, index) {
      if (index >= 0 && index <= this.count) {
        const node = new Node(element);
        let current = this.head;
        if (index === 0) {
          if (this.head === null) {
            this.head = node;
            node.next = this.head;
          } else {
            node.next = current;
            current = this.getNodeAt(this.size() - 1);
            this.head = node;
            current.next = this.head;
          }
        } else {
          const previous = this.getNodeAt(index - 1);
          node.next = previous.next;

          previous.next = node;
        }
        this.count++;
        return true;
      }
      return false;
    }
    removeAt (index) {
      if (index >= 0 && index < this.count) {
        let current = this.head;
        if (index === 0) {
          if (this.size() === 1) {
            this.head = null;
          } else {
            let last = this.getNodeAt(this.size() - 1);
            this.head = this.head.next;
            last.next = this.head;
          }
        } else {
          const previous = this.getNodeAt(index - 1);
          current = previous.next;
          previous.next = current.next;
        }
        this.count--;
        return current.element;
      }
      return;
    }
  }

  var list = new CirularLinkedList()
</script>

应用场景:

  • 循环遍历‌:可以从任意节点开始遍历整个链表,无需额外的条件判断。
  • 动态数据结构‌:循环链表可以根据需要动态增长或缩小,不需要事先定义大小。
  • 非连续存储‌:节点在内存中不必连续存储,每个节点通过指针连接。
  • 插入和删除效率高‌:在循环链表中插入或删除节点的时间复杂度为O(1),只需调整指针即可。

http://www.kler.cn/a/579921.html

相关文章:

  • 原生iOS集成react-native (react-native 0.65+)
  • Unity Shader教程:Lambert漫反射实现原理解析
  • 通过数据集微调LLM后怎么调用
  • 【算法学习计划】动态规划 -- 路径问题
  • DeepSeek进阶应用(一):结合Mermaid绘图(流程图、时序图、类图、状态图、甘特图、饼图)
  • Git系列之git checkout
  • (枚举专题)组合数枚举
  • [MERN] 使用 socket.io 实现即时通信功能
  • 力扣-单调栈-84 柱状图中最大的矩形
  • Leetcode-整数反转
  • 每日学Java之一万个为什么
  • 分布式事务的原理
  • 网络安全之tcpdump工具
  • 隐私保护在 Facebook 内容审核系统中的应用
  • 机器学习篇——决策树基础
  • python采集京东商品详情数据,API接口文档说明
  • Elasticsearch 7.x入门学习-系统架构与工作流程
  • 人工智能直通车系列13【机器学习基础】(线性回归模型实现scikit - learn)
  • 图论——差分约束
  • 贪心算法三