【问题标题】:Problems with understanding a linked list implementation理解链表实现的问题
【发布时间】:2012-03-01 13:15:53
【问题描述】:

更新:非常感谢所有回复的人!!!这让我觉得我并不孤单地努力学习 Java。请原谅我,但我想我没有充分说明我对链表和练习应用程序的不了解 -

首先 - 类定义如何包含自身的对象,好的,我知道这是递归,但它对我来说仍然是一个非常奇怪和陌生的概念。

第二 - 一个链表对象究竟如何“链接”到另一个节点?

第三个​​ - 如果两个对象用等号分隔,这意味着什么 - 第二个对象消失了,剩下的是现在指向第一个对象的“名称”,反之亦然?

然后 - 我对下面引用的程序没有理解的是:在实例化 linkList 类后,它的构造函数被调用,它首先给类 Link 私有 Link 的对象null,即设置它指向空。然后,当创建第一个新节点时,调用 public void insertFirst 方法,它将对象值赋予其变量,然后发生了一些荒谬的事情——首先指向空的对象被分配给新项目,从而使两个对象都指向什么都没有,第一个 = newLink;我完全迷路了……

我正在上一门关于算法和数据结构的大学课程,由于教授真的很刻薄,而且他的解释毫无用处,我正在尝试从 Robert Lafore 的一本名为《算法和数据结构》的书中自学。

现在我正在学习链表,书中有以下链表实现的代码示例:

链接.java:

class Link
   {
   public int iData;              // data item
   public double dData;           // data item
   public Link next;              // next link in list

   public Link(int id, double dd) { // constructor
      iData = id;                 // initialize data
      dData = dd;                 // ('next' is automatically
      }                           //  set to null)

   public void displayLink() {     // display ourself
      System.out.print("{" + iData + ", " + dData + "} ");
      }
   }

LinkList.java:

class LinkList {
   private Link first;            // ref to first link on list

   public LinkList() {             // constructor
      first = null;               // no links on list yet
      }

   public boolean isEmpty() {      // true if list is empty
      return (first==null);
      }
                                  // insert at start of list
   public void insertFirst(int id, double dd) { // make new link
      Link newLink = new Link(id, dd);
      newLink.next = first;       // newLink --> old first
      first = newLink;            // first --> newLink
      }

   public Link deleteFirst() {     // delete first item
      // (assumes list not empty)
      Link temp = first;          // save reference to link
      first = first.next;         // delete it: first-->old next
      return temp;                // return deleted link
      }

   public void displayList() {
      System.out.print("List (first-->last): ");
      Link current = first;       // start at beginning of list
      while(current != null)      // until end of list,
         {
         current.displayLink();   // print data
         current = current.next;  // move to next link
         }
      System.out.println("");
      }
   }

LinkListApp.java:

class LinkListApp {
   public static void main(String[] args) {
      LinkList theList = new LinkList();  // make new list

      theList.insertFirst(22, 2.99);      // insert four items
      theList.insertFirst(44, 4.99);
      theList.insertFirst(66, 6.99);
      theList.insertFirst(88, 8.99);

      theList.displayList();              // display list

      while( !theList.isEmpty() ) {        // until it's empty,
         Link aLink = theList.deleteFirst();   // delete link
         System.out.print("Deleted ");         // display it
         aLink.displayLink();
         System.out.println("");
         }
      theList.displayList();              // display list
      }
   }

我只是无法理解在链接列表类中插入和显示项目的代码。

新对象创建后怎么会是newLink.next = first; and first = newLink;

请帮忙!

【问题讨论】:

  • 这是一个插入作为第一项功能。 :-/
  • 我不太明白你的问题。你能描述一下你不明白的地方吗?

标签: java data-structures linked-list


【解决方案1】:

每个Link 都包含对下一个Link 元素的引用.next(最后一个元素除外,具有.next = null

LinkList 持有对其包含的第一个 Link 对象的引用 (.first)。

为了在LinkList 的前面插入一个新的Link,我们需要执行以下操作:

  1. 创建一个新的 Link 对象以插入到前面 (newLink)。
  2. 让新创建的Link指向之前的第一个Link对象作为它的.next
  3. LinkList.first 引用重置为newLink 对象,有效地覆盖之前的引用(在下方标有叉号)。

这正是发生的事情:

public void insertFirst(int id, double dd) {
    Link newLink = new Link(id, dd);
    newLink.next = first;
    first = newLink;
}

【讨论】:

  • 哇,这张图比我的好多了。为此 +1。
  • @Grigor Petrov 不客气。祝你课程顺利:)
【解决方案2】:

可能让你感到困惑的是,这个列表实现是 LIFO(后进先出),所以最后插入的元素是遍历时返回的第一个元素。

newLink.next = first; 将之前的第一个元素作为新元素的下一个(所以第二个)

first = newLink; 将新元素放在列表顶部

链表有很多不同的行为方式,这取决于您希望它们成为哪种集合(队列、堆栈)或不同的模式(单链或双链、循环)等等。

【讨论】:

    【解决方案3】:

    假设我们有一个这样的链表:

     first                -> Link("monday")
     Link("monday").next  -> Link("tuesday")
     Link("tuesday").next -> Link("wednesday")
    

    现在我们希望一周从“星期日”开始。

    首先我们为“星期日”创建一个新链接:

     Link("sunday")                             # newLink = new Link(id,dd)
    

    告诉它,它的追随者是“星期一”

     first                -> Link("monday")
     Link("sunday").next  -> Link("monday")     # newLink.next = first
     Link("monday").next  -> Link("tuesday")
     Link("tuesday").next -> Link("wednesday")
    

    最后我们修正了一周的开始

     first                -> Link("sunday")     # first = newLink
     Link("sunday").next  -> Link("monday")     
     Link("monday").next  -> Link("tuesday")
     Link("tuesday").next -> Link("wednesday")
    

    【讨论】:

      【解决方案4】:

      通过设置head = newLink;,将新的Link 添加到LinkList 对象的头部

      通过设置newLink.next = first;,将现有列表附加到新元素的next

      【讨论】:

        【解决方案5】:

        当你的新节点被添加时,它被添加到 LinkedList 的开头,所以由于指针 First 指向 List 中的第一个节点,但是当 newNode 到达同一个列表时,这指针首先必须指向新添加的节点,新添加的节点必须指向之前建立的第一个节点,这样才能成为链表的第一个节点。

        希望这张图可以进一步解释:

        这就是为什么你必须写newLink.next = first; and first = newLink;

        【讨论】:

        • @GrigorPetrov : 欢迎您并保持微笑 :-)
        猜你喜欢
        • 2022-01-20
        • 1970-01-01
        • 2021-12-11
        • 2020-02-25
        • 2013-02-22
        • 1970-01-01
        • 2022-11-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多