【问题标题】:Linked List - find Nth element at index链表 - 在索引处查找第 N 个元素
【发布时间】:2018-08-24 02:03:23
【问题描述】:

我的代码在查找链接列表的特定索引处的元素时遇到问题。

  findElement(index) {
    let currentNode = this.head;
    let count = 0;

    while (currentNode != null) {
      if (count === index) {
        return currentNode;
        count++;
        currentNode = currentNode.next;
      }
      return -1;
    }
  }

当我这样做时,我得到的是整个链表而不是一个特定的节点。因此,如果我使用 console.log(list.findElement(0)),我会得到整个链表。但是如果我控制台日志console.log(list.findElement(1)),我得到-1。但我想要的是第二个节点。下面是我的其余代码。不完全确定我的 findElement 函数出了什么问题。

class Node {
  constructor(value) {
    this.value = value;
    this.next = null;
  }
}

class LinkedList {
  constructor() {
    this.head = null;

    //Length
    this.length = 0;
  }

  //Push-front
  pushFront(value) {
    let node = new Node(value);

    node.next = this.head;

    this.head = node;

    this.length++;
  }

  //Pop-front
  popFront() {
    if (this.head != null) {
      this.head = this.head.next;
    }
    this.length--;
  }

  //Push-back
  pushBack(value) {
    let node = new Node(value);

    if (this.head === null) {
      this.head = node;
    } else {
      let currentNode = this.head;

      while (currentNode.next) {
        currentNode = currentNode.next;
      }
      currentNode.next = node;
    }
    this.length++;
  }

【问题讨论】:

    标签: javascript linked-list


    【解决方案1】:

    findElement 函数中的逻辑存在一些问题。主要问题是count 永远不会从 0 更改,因此该函数仅在头部是寻找的元素(例如 index === 0)并在任何其他输入上返回 -1 时才有效(这个“失败”返回应该移到外面while 循环)。

    这是一个将count++currentNode = currentNode.nextif 移到隐式else 的版本:

      findElement(index) {
        let currentNode = this.head;
        let count = 0;
    
        while (currentNode) {
          if (count === index) {  // found the element
            return currentNode;
          }
          
          count++;  // increment counter
          currentNode = currentNode.next;  // move to next node
        }
        
        return -1;
      }
    

    另一个问题是,如果在空列表上调用 popFront,列表的长度会减少到 -1。减量应该是有条件的以及删除。这可能会在未来的实现中造成损害,但由于您从不使用列表长度,您可以将其完全删除。

    综合起来,这是一个测试程序:

    class Node {
      constructor(value) {
        this.value = value;
        this.next = null;
      }
    }
    
    class LinkedList {
      constructor() {
        this.head = null;
        this.length = 0;
      }
      
      findElement(index) {
        let currentNode = this.head;
        let count = 0;
    
        while (currentNode) {
          if (count === index) {
            return currentNode;
          }
          
          count++;
          currentNode = currentNode.next;
        }
        
        return -1;
      }
    
      pushFront(value) {
        const node = new Node(value);
        node.next = this.head;
        this.head = node;
        this.length++;
      }
    
      popFront() {
        if (this.head != null) {
          this.head = this.head.next;
          this.length--;
        }
      }
    
      pushBack(value) {
        const node = new Node(value);
    
        if (this.head === null) {
          this.head = node;
        } 
        else {
          let currentNode = this.head;
    
          while (currentNode.next) {
            currentNode = currentNode.next;
          }
          
          currentNode.next = node;
        }
        
        this.length++;
      }
    }
    
    
    const ll = new LinkedList();
    ll.pushBack(1);
    ll.pushBack(2);
    ll.pushBack(3);
    console.log(ll);
    console.log(`First node: ${ll.findElement(0).value}`);
    console.log(`Second node: ${ll.findElement(1).value}`);
    console.log(`Third node: ${ll.findElement(2).value}`);
    console.log(`Invalid index: ${ll.findElement(22).value}`);

    【讨论】:

      【解决方案2】:

      您有一个return 语句作为if (count === index) 条件的第一行,这会阻止进一步的代码执行(意味着永远不会到达currentNode = currentNode.next)。

      您希望将return currentNode 向下移动两行,以便在函数返回之前引用后续节点。

      findElement(index) {
        let currentNode = this.head;
        let count = 0;
      
        while (currentNode != null) {
          if (count === index) {
            count++;
            currentNode = currentNode.next;
            return currentNode;
          }
          return -1;
        }
      }
      

      【讨论】:

      • 更改后,console.log(list.findElement(0)) 的结果是第二个节点而不是第一个节点。我一定是在别处做错了什么。
      • 这并没有太大的改进; countcurrentNode 在循环中不会改变。 -1 仍在循环内,因此如果第一个元素不匹配,则循环立即返回 -1
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-10
      • 2022-12-01
      • 2021-08-23
      • 2012-01-10
      • 2019-10-10
      相关资源
      最近更新 更多