博客
关于我
JS数据结构--双向链表--常见操作
阅读量:333 次
发布时间:2019-03-04

本文共 4913 字,大约阅读时间需要 16 分钟。

双向链表的优势与实现

单向链表的局限性

在单向链表中,虽然可以轻松从头到尾遍历,但回到前一个节点却非常困难。这使得单向链表难以支持复杂的操作,如插入删除等。

双向链表的优势

双向链表通过引入前驱和后驱指针,既可以从头到尾遍历,也能从尾到头遍历。这种双向连接方式有效解决了单向链表的局限性。

双向链表的特点

双向链表的每个节点包含三个部分:前驱指针(prev)、节点数据(item)和后驱指针(next)。链表的首节点的前驱指针为null,末节点的后驱指针为null。

双向链表的实现

function DoublyLinkedList() {
// 内部类:节点类
function Node(data) {
this.data = data;
this.prev = null;
this.next = null;
}
// 属性
this.head = null;
this.tail = null;
this.length = 0;
}

双向链表的基本操作

  • append方法:在链表尾部插入节点
  • DoublyLinkedList.prototype.append = function(data) {
    var newNode = new Node(data);
    if (this.length === 0) {
    this.head = newNode;
    } else {
    var current = this.head;
    while (current.next) {
    current = current.next;
    }
    current.next = newNode;
    }
    this.length += 1;
    };
    1. 链表转换成字符串:forwardString方法和backwardString方法
    2. // forwardString方法
      DoublyLinkedList.prototype.forwardString = function() {
      var current = this.head;
      var resultString = '';
      while (current) {
      resultString += current.data + '';
      current = current.prev;
      }
      return resultString;
      };
      // backwardString方法
      DoublyLinkedList.prototype.backwardString = function() {
      var current = this.head;
      var resultString = '';
      while (current) {
      resultString += current.data + '';
      current = current.next;
      }
      return resultString;
      };

      双向链表的高级操作

    3. 插入方法:按位置插入节点
    4. DoublyLinkedList.prototype.insert = function(position, data) {
      // 越界判断
      if (position < 0 || position > this.length) return false;
      var newNode = new Node(data);
      if (this.length === 0) {
      this.head = newNode;
      this.tail = newNode;
      } else {
      if (position === 0) {
      newNode.next = this.head;
      this.head.prev = newNode;
      this.head = newNode;
      } else if (position === this.length) {
      this.tail.next = newNode;
      newNode.prev = this.tail;
      this.tail = newNode;
      } else {
      var current = this.head;
      var index = 0;
      while (index++ < position) {
      current = current.next;
      }
      newNode.next = current;
      newNode.prev = current.prev;
      current.prev.next = newNode;
      current.prev = newNode;
      }
      }
      this.length += 1;
      return true;
      };
      1. 获取方法:获取指定位置的数据
      2. // 方法1(普通方法)
        DoublyLinkedList.prototype.get = function(position) {
        if (position < 0 || position >= this.length) return false;
        var current = this.head;
        var index = 0;
        while (index++ < position) {
        current = current.next;
        }
        return current.data;
        };
        // 方法2
        DoublyLinkedList.prototype.get = function(position) {
        var current = this.tail;
        var index = this.length - 1;
        while (index-- > position) {
        current = current.prev;
        }
        return current.data;
        };
        1. 查找方法:返回元素在链表中的索引
        2. DoublyLinkedList.prototype.indexOf = function(data) {
          var current = this.head;
          var index = 0;
          while (current) {
          if (current.data === data) {
          return index;
          } else {
          current = current.next;
          index++;
          }
          }
          return -1;
          };
          1. 更新方法:修改数据元素
          2. DoublyLinkedList.prototype.update = function(position, newData) {
            if (position < 0 || position >= this.length) return false;
            var current = this.head;
            var index = 0;
            while (index++ < position) {
            current = current.next;
            }
            current.data = newData;
            return true;
            };
            1. 删除方法:删除链表中的节点
            2. DoublyLinkedList.prototype.removeAt = function(position) {
              if (position < 0 || position >= this.length) return null;
              var current = this.head;
              if (this.length === 1) {
              this.head = null;
              this.tail = null;
              } else {
              if (position === 0) {
              this.head.next.prev = null;
              this.head = this.head.next;
              } else if (position === this.length - 1) {
              current = this.tail;
              this.tail.prev.next = null;
              this.tail = this.tail.prev;
              } else {
              var index = 0;
              while (index++ < position) {
              current = current.next;
              }
              current.prev.next = current.next;
              current.next.prev = current.prev;
              }
              }
              this.length -= 1;
              return current.data;
              };
              1. 删除方法:根据具体数据删除链表中的节点
              2. DoublyLinkedList.prototype.remove = function(data) {
                var index = this.indexOf(data);
                return this.removeAt(index);
                };
                1. 判断是否为空
                2. DoublyLinkedList.prototype.isEmpty = function() {
                  return this.length === 0;
                  };
                  1. 获取链表长度
                  2. DoublyLinkedList.prototype.size = function() {
                    return this.length;
                    };
                    1. 获取链表首节点数据
                    2. DoublyLinkedList.prototype.getHead = function() {
                      return this.head.data;
                      };
                      1. 获取链表末节点数据
                      2. DoublyLinkedList.prototype.getTail = function() {
                        return this.tail.data;
                        };

                        总结

                        双向链表通过引入前驱和后驱指针,显著提升了链表的灵活性和操作能力。相比单向链表,双向链表能够支持双向遍历,但在实现和内存占用上也存在一定的挑战。

    转载地址:http://ohze.baihongyu.com/

    你可能感兴趣的文章
    node.js的express框架用法(一)
    查看>>
    Node.js的交互式解释器(REPL)
    查看>>
    Node.js的循环与异步问题
    查看>>
    Node.js高级编程:用Javascript构建可伸缩应用(1)1.1 介绍和安装-安装Node
    查看>>
    nodejs + socket.io 同时使用http 和 https
    查看>>
    NodeJS @kubernetes/client-node连接到kubernetes集群的方法
    查看>>
    NodeJS API简介
    查看>>
    Nodejs express 获取url参数,post参数的三种方式
    查看>>
    nodejs http小爬虫
    查看>>
    nodejs libararies
    查看>>
    nodejs npm常用命令
    查看>>
    nodejs npm常用命令
    查看>>
    Nodejs process.nextTick() 使用详解
    查看>>
    NodeJS yarn 或 npm如何切换淘宝或国外镜像源
    查看>>
    nodejs 中间件理解
    查看>>
    nodejs 创建HTTP服务器详解
    查看>>
    nodejs 发起 GET 请求示例和 POST 请求示例
    查看>>
    NodeJS 导入导出模块的方法( 代码演示 )
    查看>>
    nodejs 开发websocket 笔记
    查看>>
    nodejs 的 Buffer 详解
    查看>>