Java 使用单个类实现链表?

Java 使用单个类实现链表?,java,data-structures,linked-list,underscore-java,Java,Data Structures,Linked List,Underscore Java,我不熟悉数据结构。在学习时,我无法理解这两种链表实现之间的区别 在我所看到的大部分地方,每个人都在使用下面提到的链表的第一个实现 分两类: class Node{ int data; int value; Node next; Node(int data){ this.data = data; this.next = null; } Node(int data, Node next){ this.

我不熟悉数据结构。在学习时,我无法理解这两种链表实现之间的区别

在我所看到的大部分地方,每个人都在使用下面提到的链表的第一个实现

分两类:

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

    Node(int data, Node next){
        this.next = next;
        this.data = data;
    }
}

class LinkedList{
    Node head;
    LinkedList(Node head){
        this.head = head;
    }
    LinkedList(){
        this.head = null;
    }

    void insert(int data){
        //it will insert at the end
        //logic
     }
    //Other methods.

}
但我的问题是,为什么我们需要两个类来实现它。假设我使用以下实现:

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

    Node(int data, Node next){
        this.next = next;
        this.data = data;
    }

    void appendToTail(int d){
        Node node = new Node(4);
        Node traversal = this;

        while(traversal.next!=null){
            traversal = traversal.next;
        }
        traversal.next = n; 
    }
}

现在我可以在一节课上用它做所有的事情,不是吗?请告诉我这种方法有什么问题,因为它使人非常困惑。

单类方法看起来相当有限,不是吗?使用链表的好处是可以方便地访问它的开头和结尾。使用链表可以显著提高运行时间,而不是遍历每个节点来查找尾部。在数据结构课程中,删除无疑是一个至关重要的主题,当涉及到删除时,两类方法比一类方法实用得多。在两类方法中,可以根据需要迭代并重新分配正面或反面。在单类方法中,无论您首先创建哪个节点都意味着一切,因为您不能定义头或尾,所以在删除发生后跟踪所有节点变得非常困难。TLDR:two-class方法允许更容易的访问,从而加快运行时。

在第二个版本中,
节点
类也充当列表的标题。但问题是,如果您有一个
节点
实例,则无法判断它当前是否是列表的头

为什么这很重要

考虑在列表开始时添加一个新元素时会发生什么;e、 g

Node list1 = new Node(1, null);
Node list2 = new Node(2, list1);
现在,
list1
可以是一个列表,也可以是另一个列表的一部分。。。或者两者兼而有之。仅仅通过查看
节点
对象本身的表示,无法知道哪种情况是这样

事实上,不难举出错误可能导致名单进入不再是“类似名单”的国家的例子

相比之下,在具有不同的
LinkedList
Node
类型的版本中,角色之间存在着明显的区别。如果随后将
节点
类设置为
链接列表
的私有内部类,则后者可以管理数据结构,以防止形成不需要的结构(例如循环)


现在我可以在一节课上用它做所有的事情,不是吗

这是真的

但真正的问题是,通过使用两个类(以及适当地使用其他Java语言特性),您可以创建一个抽象,该抽象在任何时候都像一个适当的列表

请告诉我这种方法有什么问题,因为它使人非常困惑


的确如此。明智地使用抽象可以减少混乱。通过将列表数据结构和操作它们的方法隐藏在
LinkedList
类的抽象边界之后,您可以更轻松地编写可以安全使用列表的代码。

这就是我正在搜索的内容。。。你的意思是这是限制,因为我们不必在尾部访问,而且它还缺少一些其他功能,比如在结尾处删除。。雷特?非常感谢您的澄清。。因此,结论是我们可以这样想,但由于缺乏功能,我们应该始终使用两类实现。@sourabhsharma是的,简而言之,一类方法可以工作,但由于我在回答中所述的原因,它更难使用。如果你能批准我的答案,这样它可以帮助其他人,那就太棒了:在一些语言中,比如Lisp(其中链表是一级公民),列表只是一个节点,所以它更像你的第二个版本。
list2.next = list1;  // creates a cycle!