【问题标题】:How to find the first value in a linked list?如何找到链表中的第一个值?
【发布时间】:2019-05-06 13:44:10
【问题描述】:

我有一个给定的链接列表,我需要通过 getFirst 方法找到列表中的第一个值。如果值为 null,我需要显示错误消息并退出程序。链接列表已经给了我链接,所以:

class MyLinkedList
{
   private class Node            // inner class
   {
      private Node link;
      private int x;
   }
   //----------------------------------
   private Node first = null;    // initial value is null
   //----------------------------------
   public void addFirst(int d)
   {
      Node newNode = new Node(); // create new node
      newNode.x = d;             // init data field in new node
      newNode.link = first;      // new node points to first node
      first = newNode;           // first now points to new node
   }
   //----------------------------------
   public void traverse()
   {
     Node p = first;
      while (p != null)            // do loop until p goes null
      {
         System.out.println(p.x);  // display data
         p = p.link;               // move p to next node
      }
   }
}
//==============================================
class TestMyLinkedList
{
   public static void main(String[] args)
   {
      MyLinkedList list = new MyLinkedList();
      list.addFirst(1);
      list.addFirst(2);
      list.addFirst(3);
      System.out.println("Numbers on list");
      list.traverse();
   }
}

这是我尝试的方法:

 public static Node getFirst(Node list)
  {
    if (list == null)
    {
      System.out.println("Error!");
      System.exit(1);
    }
    return MyLinkedList.first;
  }

我知道这并不完全正确,我们刚在课堂上开始这样做,所以我无法理解它发生了什么。谢谢!

【问题讨论】:

  • 您实际上拥有的只是一个节点,您不断替换第一个节点,因此其他东西都丢失了。也许你应该有一个指向第一个节点和最后一个节点的指针?这样您就可以立即添加到末尾或沿两个不同的方向遍历
  • 请阅读minimal reproducible example 并相应地增强您的问题。 “不完全正确”不是正确的问题描述。

标签: java methods linked-list


【解决方案1】:

您问题中的MyLinkedList 类遵循堆栈数据结构的模式(在我写这个答案的时候)。即:每次添加新元素时,新元素都会将之前添加的元素替换为第一个元素。

如果您按顺序添加了元素 1,2,3,我猜您想将 1 作为您的第一个元素。如果我错了,请纠正我。

在这种情况下,你的链表和它的检索应该是这样的:

(注意:我避免使用private vars 、public getter 、 settter 等;以使代码易于阅读。但读者应该添加它们。)

class Node{ int x; Node next; }

class LinkedList
{ Node head,tail;
  void add(int y)
  { Node node = new Node();
    node.x=y;
    if(head==null)
      head = tail = node;
    else
      tail = tail.next = node;
  }
  int getFirst()
  { if(head!=null)
      return head.x;
    else
      throw new java.util.NoSuchElementException("List is empty");
  }
}

如果您查看java.util.LinkedList,您会发现通常用于链表的方法。如果这不是一个家庭作业问题,那么我建议你不要重新发明轮子。只需使用现有的库。

如果您必须使用堆栈数据结构,并且您无法更改它,那么我建议您必须像这样更改您的getFirst()

  int getFirst()
  { if(tail!=null)
      return tail.x;
    else
      throw new java.util.NoSuchElementException("List is empty");
  }

如果您不允许在代码中添加Node tail,那么您的getFirst() 将如下所示:

  int getFirst()
  { if(head==null)
      throw new java.util.NoSuchElementException("List is empty");
    Node node = head;
    while(node.next!=null)
      node=node.next;
    return node.x;
  }

【讨论】:

    【解决方案2】:

    请注意,第一个值与第一个 Node 链接到 null。然后你必须检查两件事

    1. Node == null(你知道了)
    2. Node.next == null(你必须这样做)

    Node.next == null。这意味着Node 是第一个值,因为它与初始Node 链接到null

    那么你有

    public static Node getFirst(Node list)
    {
        // if the list is empty
        if (list == null)
        {
          System.out.println("Error!");
          System.exit(1);
        } else if(list.link == null) {
          // this is the first value!
          return list;
        } else {
        // keep searching recursive with the next Node
        return getFirst(list.link);
        }
    }
    

    【讨论】:

      【解决方案3】:

      您应该检查 first 不为空,以便执行您在问题中描述的操作。此外,第一个节点自动引用自身有点奇怪,因为通常它会保留为 null,直到您添加另一个节点

      【讨论】:

        【解决方案4】:

        我认为您应该查看https://docs.oracle.com/javase/7/docs/api/java/util/LinkedList.html 并初步了解链表的行为。一旦您对它的行为方式有所了解,您就可以考虑如何围绕它添加功能。现在你只有一个方法,你调用的次数比你应该调用的多。还可能有帮助的是创建一个接口并记录它,以便您知道每个方法应该做什么。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-08-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-04-07
          相关资源
          最近更新 更多