【问题标题】:Why does my while loop produce an extra value in Java?为什么我的 while 循环会在 Java 中产生额外的值?
【发布时间】:2021-08-17 13:12:27
【问题描述】:

我正在尝试在 Java 中创建一个 while 循环,用于计算双向链表中的节点数。然而,我的 while 循环产生了额外的价值,我似乎无法弄清楚为什么。有人可以帮我吗?

下面的方法用于统计我在 Main Method 中定义的列表中的节点数。我在 main 方法中调用了 getListSize() 方法。

 public static <E> int Size(Linked<E> L) { 

      int counter=0;
      while (L.header != null && L.header != L.trailer)
      {
        L.header= L.header.getNext();
        counter++;
        
      }
      return counter;
  }


public static void main(String[] args)
  {
     Linked<String> list = new Linked<String>();
     list.addFirst("1");  
     list.addFirst("4");
      list.addLast("3");
      list.addLast("2");
      
            
      System.out.println(Size(list));
      
  }

但我得到的输出是 5 而不是 4

节点和链接类


公共类链接{

  public static class Node<E> {

    private E element;               
    private Node<E> prev;           
    private Node<E> next;            

    
    public Node(E e, Node<E> p, Node<E> n) {
      element = e;
      prev = p;
      next = n;
    }

    public E getElement() { return element; }

    public Node<E> getPrev() { return prev; }

    public Node<E> getNext() { return next; }

    public void setPrev(Node<E> p) { prev = p; }
    public void setNext(Node<E> n) { next = n; }
    
  } 


  
  public Node<E> header;                    
  public Node<E> trailer;                   
  private int size = 0;                      

  
  public Linked() {
    header = new Node<>(null, null, null);      
    trailer = new Node<>(null, header, null);   
    header.setNext(trailer);                    
  }

}

【问题讨论】:

  • 这似乎是双向链表的自定义实现。你确定你的实现没有错误吗?或许您应该显示该代码。
  • L.header != L.trailer有什么用?好像你不会计算最后一个节点,但你说输出是 5 而不是 4。
  • 顺便说一句,您不应该像那样更改 L.header 。您正在覆盖您的头指针,该列表将毫无用处。相反,在函数的开头创建一个变量 pointer = l.header 并设置它的值。
  • @MostNeededRabbit L.header != L.trailer 检查列表的头部和尾部是否相同,这意味着列表中只有一个元素。如果我删除它,那么我会得到 6
  • @GabeSechan 谢谢,我会做出这些改变

标签: java while-loop linked-list counter


【解决方案1】:

我们不应该关心头部和尾部是否相同,因为节点将具有next = null

代码:

public static int size(Linked<Node> L) {
    int counter = 0;
    Node curr = L.header;

    while (curr != null) {
        counter++;
        curr = curr.next;
    }

    return counter;
}

例子:

Node a = new Node("A");
Linked<Node> linked = new Linked<>(a, a);

System.out.println(size(linked)); // 1

--------------------------------------
Node a = new Node("A");
Node b = new Node("B");
a.next = b;
Linked<Node> linked = new Linked<>(a, b);

System.out.println(size(linked)); // 2

--------------------------------------
Node a = new Node("A");
Node b = new Node("B");
Node c = new Node("C");
a.next = b;
b.next = c;
Linked<Node> linked = new Linked<>(a, c);

System.out.println(size(linked)); // 3

【讨论】:

  • 我将代码调整为上面的代码,但我的输出现在是 6 而不是 4。你所做的一切对我来说都很有意义,但我不明白为什么我的输出返回错误的数字
  • @kia 你能分享一下LinkedNode的课程吗?我认为问题出在那儿。
  • 我已经添加了上面的类
【解决方案2】:

至少部分问题是因为您将两个“空”节点添加到列表中,然后计算它们。这是一种奇怪的做事方式。

你还没有向我们展示你的 add() 方法,所以可能还有更多的错误潜伏着。

  public Linked() {
    header = new Node<>(null, null, null);      // <- Extra   
    trailer = new Node<>(null, header, null);   // <- Extra   
    header.setNext(trailer);                    
  }

这很奇怪,我认为您的讲师可能已经给您特别说明了如何处理这些额外的节点。您可能想咨询您的讲师,您可能错过了部分讲座。

顺便说一句,这两个节点不会与== 进行比较,因此您不能使用它来结束迭代。我还注意到您的列表是循环的。尾部指向头部,头部被设置为指向尾部。这也很奇怪,我想你应该问你的导师澄清一下,你写的代码似乎没有考虑到这一点。

此外,正如 Gabe 所指出的,您在计数期间似乎覆盖了 header 的值。这会搞砸一切。

 public static <E> int Size(Linked<E> L) { 

      int counter=0;
      Node<E> current = L.header;
      while (current != null && L.header != L.trailer)
      {
        current = L.header.getNext();
        counter++;
        
      }
      return counter;
  }

最后,上面的代码仍然是错误的。我认为您的讲师专门编写了那个“奇怪”的代码,以防止您直接从互联网上复制代码。这里需要做一些额外的思考。我给了你一个提示(关于 L.header 被覆盖),但我认为你应该和你的导师谈谈其余的。

【讨论】:

  • 谢谢,我明白了。代码实际上是由教授提供的,我们被要求简单地创建一个方法来计算列表中节点的数量。我完全忽略了创建 2 个空节点的事实。这有很大帮助。
  • 嗯,调试时的一项基本技能就是阅读别人的代码,所以注意他们是如何做事的。
猜你喜欢
  • 2012-11-07
  • 2022-12-18
  • 2020-11-03
  • 1970-01-01
  • 2016-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-29
相关资源
最近更新 更多