【问题标题】:Head node in linked lists链表中的头节点
【发布时间】:2011-05-28 00:51:40
【问题描述】:

我无法理解链表数据结构中第一个节点或所谓的头的性质是什么。链表由节点组成,每个节点包含一些数据和到链表中另一个节点的链接。但是第一个节点是包含数据和到第二个节点的链接的节点吗?还是它只包含到节点的链接(没有数据)?我认为链表中的第一个节点既有数据又有到另一个节点的链接,但在一本介绍性书中解释说,头是一个节点,但它是一个链接,可以让你到达第一个节点。同时head是节点类型的变量。为什么会这样? (如果这很重要,我正在使用 Java)。谢谢。

【问题讨论】:

    标签: java linked-list head


    【解决方案1】:

    这些被称为“虚拟”标头节点,它们允许您编写适用于空列表和非空列表的通用代码。

    通常,如果您想在列表末尾插入Node,则需要两种情况。如果head 为空,表示列表为空,则将head 设置为新的Node。如果head 不为空,则跟随next 指针直到获得最后一个Node,并将next 指针设置为新的Node

    但是,如果您使用虚拟标头,head 将永远不会为空。它将是一个Node,带有一个空的next 指针,您可以将它指向您的新Node,就像列表确实包含节点时一样。

    【讨论】:

      【解决方案2】:

      @falmarri 回答,您可以采用任何一种方式实现它。头节点类似于单链表中的任何其他节点。它只是一个起始节点,我们可以用它遍历链表的其余部分。我们可以将 head 实现为节点或指针。

      【讨论】:

        【解决方案3】:

        把它想象成一个节点是一个对象,它有一个变量“data”来保存值,另一个变量“next”指向另一个节点对象来建立链接。 请参阅下面的 java 类。

        public class ListNode {
        private int data;
        private ListNode next = null;
        
        public ListNode() {
            // TODO Auto-generated constructor stub
        }
        //constructor for creating a listNode
        public ListNode(int data){
            this.data = data;
        }
        /*below are setters and getters  */
        public void setData(int data){
            this.data = data;
        }
        public int getData(){
            return this.data;
        }
        public void setNext(ListNode next){
            this.next = next;
        }
        public ListNode getNext(){
            return this.next;
        }
        }
        

        这就是我要链接它的方式。

        //create 3 list node objects
            ListNode one = new ListNode(1);
            ListNode two = new ListNode(2);
            ListNode three = new ListNode(3);
        
            one.setNext(two);
            two.setNext(three);
        

        但请注意,我们需要知道头节点以进行任何进一步的操作,例如在列表的末尾、开头或随机位置添加 ListNode。

        在我们的例子中,头节点是列表链的起点。

        希望它清除:)

        谢谢 普尼斯

        【讨论】:

        • 括号中ListNode one = new ListNode(1); 中的数字1ListNode two = new ListNode(2); 中的数字2 指的是什么?它有什么作用?
        • @Sam,见 ListNode(int data) 的构造函数参数。它获取数据并将其分配给对象数据变量。
        【解决方案4】:

        您可以通过任何一种方式实现它。不过,没有数据而只有一个链接的第一个节点将是一个非常奇怪的实现。

        【讨论】:

        • 不一定。拥有一个“哨兵”第零节点可以简化您可能希望在链表上执行的许多操作 - 例如,许多操作不再需要显式检查空列表。
        • 好吧,你是对的,但我想这取决于你要解决的问题。我从来没有亲自使用过第一个节点为空的链接列表。
        • jdk6 linkedList 的实现就在那里。
        【解决方案5】:

        头节点通常与任何其他节点一样,只是它在逻辑上位于列表的开头,并且没有其他节点指向它(除非您有一个双向链表)。

        由于没有其他节点指向它,并且您还需要一种简单的方法来查找列表的开头,因此通常存储一个单独的指向指向头节点的节点的指针。这个指针本身不是一个节点,只是一个指向一个节点的指针。

        【讨论】:

        • 根据我的书,这个单独的指针与其他节点具有相同的数据类型。那么,它本身并不是一个节点,而是和节点具有相同的类型,这样对吗?
        • 这取决于你用什么语言编写。在java之类的东西中,指向第一个节点的指针很可能必须是一个节点。在 C 或 C++ 之类的东西中,你可以有一个真正的指针。
        【解决方案6】:

        如果这是在 C++ 中,您可能会更容易理解,但标头节点更多地只是一个参考,您可以使用它来获得对整个列表的初始访问权限。它引用列表中的第一个“完整”节点,该节点包含列表数据集中的数据项以及对下一个节点的引用。如果这是 C++,一个节点实际上只是一个指向数据结构的“指针”,它只是编译器的内存地址。如果您没有指向您的链表的标头节点,那么它将在“以太”中丢失,再也不会被访问 - 同时仍占用内存空间。

        由于 Java 在幕后为您解决了这个问题,您实际上不必担心指针。但是,这可能是您感到困惑的原因。由于隐藏了太多细节,如果没有任何概念背后的先验知识,您将不得不接受语法规则而不知道其背后的原因。

        从概念上讲,数组是一种列表,就像链表也是一种列表一样。数组在内存中按顺序放置,而链表则不是。数组的成员仅引用其数据项,但由于成员被放置在内存中的位置,因此您可以通过将整数值乘以该数据项的数据类型的大小添加到整个数组的引用来访问它们。这与链表的不同之处在于链表不是按顺序放置的,因此必须使用更复杂的数据结构来组成列表 - 即“节点”。

        但是,由于链表在内存中没有按任何顺序放置,编译器不必为它留出一大块数据,这就是为什么它可以有任何长度的原因每次更改长度时都必须重新创建一个新的。这与数组不同,因为数组的长度是静态的。此外,数组由其第一个成员引用,即(对于名为“a”的数组)这将是“a[0]”或等效的“a”,如果这是 C。但是,链表不会像这样工作,这就是为什么你有一个“标题”或“虚拟”节点来引用整个事物。

        关于头节点的另一件事是,在对链表执行各种操作时,您还可以创建一个与“头节点”结构相似的节点,以帮助您对链表执行操作。

        【讨论】:

          【解决方案7】:

          将头节点添加到链表中很好,因为您在插入或删除第一个节点时不再需要专门化您的方法,您可以像处理其他节点一样处理它们。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2013-07-23
            • 1970-01-01
            • 2017-01-29
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-06-15
            相关资源
            最近更新 更多