【问题标题】:Implementation of linked list using single class?使用单类实现链表?
【发布时间】:2021-03-01 09:32:04
【问题描述】:

我是数据结构的新手。在学习它时,我无法理解这两种链表实现之间的区别。

在我所见最多的地方,每个人都在使用下面提到的链表的第一个实现。

通过两个类:

 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; 
    }
}

现在我可以在一个班级里用它做所有事情,不是吗?请告诉我这种方法有什么问题,因为它非常混乱。

【问题讨论】:

  • 在某些语言中,比如 Lisp(其中链表是 the 一等公民),列表只是一个节点,所以它更像您的第二个版本。

标签: java data-structures linked-list underscore-java


【解决方案1】:

在第二个版本中,Node 类也用作列表的头部。但问题是,如果你有一个Node 实例,你无法判断它当前是否是列表的头部。

为什么重要?

考虑一下当你在列表的开头添加一个新元素时会发生什么;例如

Node list1 = new Node(1, null);
Node list2 = new Node(2, list1);

现在,list1 可以是一个列表,也可以是另一个列表的一部分……或者两者兼而有之。仅通过查看 Node 对象本身的表示,无法知道是哪种情况。

确实,不难想出一些错误可能导致列表进入不再“类似列表”的状态的示例。

list2.next = list1;  // creates a cycle!

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


现在我可以在一个班级里用它做所有事情不是吗?

这是真的。

但真正的意义在于,通过两个类(并适当使用其他 Java 语言特性),您可以创建一个抽象,该抽象始终表现就像一个适当的列表。

请告诉我这种方法有什么问题,因为它非常混乱。

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

【讨论】:

    【解决方案2】:

    one-class 方法看起来相当有限,不是吗?使用链接列表的好处是可以轻松访问它的头部和尾部。拥有一个链表可以显着提高运行时间,而不是通过每个节点来寻找尾部。说到删除,这绝对是数据结构课程中的一个关键话题,二分类方法比一分类方法实用得多。在二分类方法中,您可以随意迭代和重新分配头或尾。在 one-class 方法中,首先创建的节点意味着一切,并且由于您无法定义头部或尾部,因此在删除发生后跟踪所有节点变得非常具有挑战性。 TLDR:二类方法允许更轻松的访问,进而加快运行时间。

    【讨论】:

    • 这就是我一直在寻找的......你的意思是它限制了我们不必在尾部访问,而且它还缺少一些其他功能,比如从末尾删除等等...... ryt ?非常感谢您的澄清。所以我们可以这样认为的结论,但由于缺乏功能,我们应该始终采用两类实​​现。
    • @sourabhsharma 是的,简而言之,一类方法可以工作,但由于我的回答中所述的原因,使用起来要困难得多。如果您可以批准我的回答以便它可以帮助其他人,那就太棒了:D
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-20
    • 2014-04-07
    • 1970-01-01
    • 2013-12-03
    • 2014-03-07
    • 1970-01-01
    相关资源
    最近更新 更多