双向链表[js实现] 【7】

86 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第30天,点击查看活动详情

remove(element)

用途: 根据传进来的元素删除这个元素。

对于这个方法,我们可以通过元素找到相应的索引,然后再通过索引删除相应的元素。这里完全可以去调用我们之前写好的indexOf()方法和removeAt()方法即可。

 TwoWayLinkList.prototype.remove = function (data) {
          console.log(this)
          // 根据data获取下标
          var index = this.indexOf(data);
          // 删除对应位置的节点
          return this.removeAt(index);
  };

测试一下

      console.log(list.toString());
      console.log(list.remove('bce'));
      console.log(list.toString());

image.png

isEmpty

如果length为0则返回false否则返回true

  TwoWayLinkList.prototype.isEmpty = function () {
          return this.length === 0;
    };

size

返回的是链表的长度

TwoWayLinkList.prototype.size = function () {
          return this.length;
        };

getHead

获取第一个元素

TwoWayLinkList.prototype.getHead = function () {
          return this.head.data;
        };

getTail

 TwoWayLinkList.prototype.getTail = function () {
          return this.tail.data;
  };

完整实现

   <script>
      // 封装双向链表
      function TwoWayLinkList() {
        // 属性
        this.head = null;
        this.tail = null;
        this.length = 0;
        // 用于创建节点的内部类
        function Node(data) {
          this.data = data;
          this.prev = null;
          this.next = null;
        }
        /**
         *  1.append()
         * */
        TwoWayLinkList.prototype.append = function (data) {
          // 创建节点
          var newNode = new Node(data);
          if (this.length == 0) {
            this.head = newNode;
            this.tail = newNode;
          } else {
            this.tail.next = newNode;
            newNode.prev = this.tail;
            this.tail = newNode;
          }
          this.length += 1;
        };
        /**
         *  2.链表转换为字符串
         *
         * */
        TwoWayLinkList.prototype.forwardString = function (data) {
          // 指向第一个节点
          var current = this.tail;
          //
          var result = '';
          // 依次向前遍历 只要有值就拼接到字符串上
          while (current) {
            result += current.data + ' ';
            current = current.prev;
          }
          return result;
        };
        TwoWayLinkList.prototype.backwardString = function (data) {
          // 指向第一个节点
          var current = this.head;
          //
          var result = '';
          // 依次向后遍历 只要有值就拼接到字符串上
          while (current) {
            result += current.data + ' ';
            current = current.next;
          }
          return result;
        };
        TwoWayLinkList.prototype.toString = function (data) {
          return this.backwardString();
        };
        /**
         *  isnert(position,data)
         * */
        TwoWayLinkList.prototype.insert = function (position, data) {
          // 越界判断
          if (position < 0 || position > this.length) return false;
          // 根据data创建新的节点
          var newNode = new Node(data);
          // 判断原来的链表是否为空
          if (this.length == 0) {
            this.head = newNode;
            this.tail = newNode;
          } else {
            // 判断position是否为0
            if (position == 0) {
              // 当前的head指向原来的节点,当新节点插入后新节点就是他的prev了
              this.head.prev = newNode;
              // 当前的head指向原来的节点,此时新节点的next就是原来的节点(也就是head)
              newNode.next = this.head;
              // 改变head的指向
              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;
        };
        TwoWayLinkList.prototype.get = function (position) {
          // 越界判断
          if (position < 0 || position >= this.length) {
            return false;
          }
          // this.length / 2 > position :从前向后遍历
          // this.length / 2 < position :从后向前遍历

          if (this.length / 2 >= position) {
            // 获取元素
            var current = this.head;
            var index = 0;
            while (index++ < position) {
              current = current.next;
            }
          } else {
            // 获取元素
            var current = this.tail;
            // 元素的下标只到length-1
            var index = this.length - 1;
            while (index-- > position) {
              current = current.prev;
            }
          }

          return current.data;
        };
        // indexOf
        TwoWayLinkList.prototype.indexOf = function (data) {
          // 1.定义变量
          var current = this.head;
          var index = 0;
          // 2.查找和data相同的节点。
          while (current) {
            if (current.data == data) {
              return index;
            } else {
              current = current.next;
              index += 1;
            }
          }
          return -1;
        };
        // update
        TwoWayLinkList.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;
        };
        TwoWayLinkList.prototype.removeAt = function (position) {
          // 越界判断
          if (position < 0 || position >= this.length) {
            return false;
          }
          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;
              // current的这个节点因为没有被引用最后会被销毁
            }
          }
          this.length -= 1;
          return current.data;
        };
        TwoWayLinkList.prototype.remove = function (data) {
          console.log(this);
          // 根据data获取下标
          var index = this.indexOf(data);
          // 删除对应位置的节点
          return this.removeAt(index);
        };
        TwoWayLinkList.prototype.isEmpty = function () {
          return this.length === 0;
        };
        TwoWayLinkList.prototype.size = function () {
          return this.length;
        };
        TwoWayLinkList.prototype.getHead = function () {
          return this.head.data;
        };
        TwoWayLinkList.prototype.getTail = function () {
          return this.tail.data;
        };
      }
      // 测试
      var list = new TwoWayLinkList();
      list.append('abc');
      list.append('bce');
      list.append('ghg');
      //   console.log(list.insert(0, 'insert'));
      //   console.log(list.insert(4, 'insert1'));
      //   console.log(list.insert(3, 'insert2'));
      //   console.log(list.toString());
      //   console.log(list.get(4));
      // console.log(list.indexOf('bce'));
      //   console.log(list.update(0, 'sdsds'));
      //   console.log(list.update(2, 'ss'));
      console.log(list.toString());
      console.log(list.remove('bce'));
      console.log(list.toString());
    </script>