XPoet/js-data-structure-and-algorithm

关于双向链表remove方法的疑问

Closed this issue · 4 comments

// remove(data) 删除指定 data 所在的节点(继承单向链表) remove(data) { return super.remove(data); }
但是单向链表中的remove方法仅仅只改变了next指针,对currentNode.next.pre没做任何修改是不是会产生问题?
是不是还应该加上这一条:
currentNode.next.pre = previousNode

XPoet commented

@venvillssd
不需要。
虽然 remove(data) 继承的是单向链表的 remove(data),但在双向链表里重写了 removeAt(position),实际用的双向链表的 removeAt(position),有对 prev 指向做处理。

双向链表

  // remove(data) 删除指定 data 所在的节点(继承单向链表)
  remove(data) {
    return super.remove(data);
  }

  // removeAt() 删除指定位置的节点
  // 重写 removeAt()
  removeAt(position) {
    // 1、position 越界判断
    if (position < 0 || position > this.length - 1) return null;

    // 2、根据不同情况删除元素
    let currentNode = this.head;
    if (position === 0) { // 删除第一个节点的情况

      if (this.length === 1) { // 链表内只有一个节点的情况
        this.head = null;
        this.tail = null;
      } else { // 链表内有多个节点的情况
        this.head = this.head.next;
        this.head.prev = null;
      }

    } else if (position === this.length - 1) { // 删除最后一个节点的情况

      currentNode = this.tail;
      this.tail.prev.next = null;
      this.tail = this.tail.prev;

    } else { // 删除 0 ~ this.length - 1 里面节点的情况

      let targetIndex = 0;
      let previousNode = null;
      while (targetIndex++ < position) {
        previousNode = currentNode;
        currentNode = currentNode.next;
      }

      previousNode.next = currentNode.next;
      currentNode.next.perv = previousNode;

    }

    this.length--;
    return currentNode.data;
  }

单向链表

// remove(data) 删除指定 data 的节点,并返回删除的那个节点
  remove(data) {
    return this.removeAt(this.indexOf(data));
  }

你可以把整套代码下载下来测试

@venvillssd
不需要。
虽然 remove(data) 继承的是单向链表的 remove(data),但在双向链表里重写了 removeAt(position),实际用的双向链表的 removeAt(position),有对 prev 指向做处理。

双向链表

  // remove(data) 删除指定 data 所在的节点(继承单向链表)
  remove(data) {
    return super.remove(data);
  }

  // removeAt() 删除指定位置的节点
  // 重写 removeAt()
  removeAt(position) {
    // 1、position 越界判断
    if (position < 0 || position > this.length - 1) return null;

    // 2、根据不同情况删除元素
    let currentNode = this.head;
    if (position === 0) { // 删除第一个节点的情况

      if (this.length === 1) { // 链表内只有一个节点的情况
        this.head = null;
        this.tail = null;
      } else { // 链表内有多个节点的情况
        this.head = this.head.next;
        this.head.prev = null;
      }

    } else if (position === this.length - 1) { // 删除最后一个节点的情况

      currentNode = this.tail;
      this.tail.prev.next = null;
      this.tail = this.tail.prev;

    } else { // 删除 0 ~ this.length - 1 里面节点的情况

      let targetIndex = 0;
      let previousNode = null;
      while (targetIndex++ < position) {
        previousNode = currentNode;
        currentNode = currentNode.next;
      }

      previousNode.next = currentNode.next;
      currentNode.next.perv = previousNode;

    }

    this.length--;
    return currentNode.data;
  }

单向链表

// remove(data) 删除指定 data 的节点,并返回删除的那个节点
  remove(data) {
    return this.removeAt(this.indexOf(data));
  }

你可以把整套代码下载下来测试

确实是我阅读代码的时候没有仔细查看, 代码是没有问题的. 感谢作者耐心解答 : -)

@XPoet 另外作者您好, 您写的这套笔记我已经全部学习了一遍,,非常优质。请问我可以转载至自己搭建的博客上吗?我会在第一行标明转载的来源~

XPoet commented

@venvillssd 👌 没问题