Java 为什么要为链表设置父类

Java 为什么要为链表设置父类,java,data-structures,linked-list,Java,Data Structures,Linked List,这是一个一般性的问题,可能是关于OOP的概念。我刚刚开始用JAVA实现DS。 我正在尝试实施链表,在所有在线资源上,我看到了类似的做法: 创建一个节点类 创建具有节点对象的类链表 类似地,我看到了堆栈、队列和树。我的问题是,如果我实现LinkedList时只有一个类,如下所示: class LinkList { int data; LinkList next; } 我仍然可以做所有的手术。因此,拥有包含根或头的第二个类的概念只是为了OOP或其他目的? 我编写了以下代码,它

这是一个一般性的问题,可能是关于OOP的概念。我刚刚开始用JAVA实现DS。 我正在尝试实施链表,在所有在线资源上,我看到了类似的做法:

  • 创建一个节点类
  • 创建具有节点对象的类链表
  • 类似地,我看到了堆栈、队列和树。我的问题是,如果我实现LinkedList时只有一个类,如下所示:

     class LinkList {
         int data;
         LinkList next; }
    
    我仍然可以做所有的手术。因此,拥有包含根或头的第二个类的概念只是为了OOP或其他目的? 我编写了以下代码,它运行良好,无需使用头指针。我在所有方法中都使用了一个引用变量,而主类的对象仍然保持头部的轨迹

    /* package codechef; // don't place package name! */
    
    import java.util.*;
    import java.lang.*;
    import java.io.*;
    
    class LinkList {
        int data;
        LinkList next;
    
        LinkList(){
            data = 0;
            next = null;
        }
    
        LinkList(int data) {
            this.data = data;
            next = null;
        }
        LinkList insertAtBegin(int data){
            LinkList newBegin = new LinkList(data);
            newBegin.next = this;
            return newBegin;
        }
        void insertAtPlace(int data, int insertData){
            LinkList newNode = new LinkList(insertData);
            LinkList iterator = this;
            while(iterator!=null && iterator.data!=data){
                iterator = iterator.next;
            }
            if(iterator.data == data)
            {
                newNode.next = iterator.next;
                iterator.next = newNode;
            }
        }
        void insertAtLast(int data) {
            if(next == null){
                next = new LinkList(data);
            }
            else{
                next.insertAtLast(data);
            }
        }
    
    }
    
    /* Name of the class has to be "Main" only if the class is public. */
    class Codechef
    {
        public static void main (String[] args) throws java.lang.Exception
        {
            // your code goes here
            LinkList linkList = new LinkList(6);
            linkList.insertAtLast(5);
            linkList.insertAtLast(3);
            linkList.insertAtLast(2);
            linkList.insertAtLast(1);
    
            linkList = linkList.insertAtBegin(10);
            LinkList iterator = linkList;
            while(iterator!=null){
                System.out.print(iterator.data);
                iterator = iterator.next;
            }
            System.out.print("\n");
            linkList.insertAtPlace(5,-1);
            iterator = linkList;
            while(iterator!=null){
                System.out.print(iterator.data);
                iterator = iterator.next;
            }
        }
    }
    

    您必须在某个地方跟踪链接列表的标题。否则,您将如何迭代整个列表,或搜索列表中的元素

    如果您的
    链接列表
    本质上是一个节点(包含数据和对下一个节点的引用),则必须在跟踪列表的头节点的某个单独类中实现所有链接列表操作(添加、删除等)

    这将使您回到使用节点类的链表类


    对于您添加的代码,
    LinkList insertabegin(int data)
    仅在列表的第一个节点上调用节点时,才会在列表的开头插入节点。但是,没有什么可以阻止您在列表的任何节点上调用它,在这种情况下,它将返回一个新列表,该列表以新元素开始,以原始列表的子列表结束。

    在第一个示例中,您的LinkList类将只是一个节点类,因为它保存数据和它后面的节点

    拥有LinkedList类的一般目的是为列表提供一个“包装器”,它只是一个包含列表头(在链接列表的情况下,就是列表)的类,可能还有一些功能,比如find函数或您需要的任何其他功能


    因此,在您的示例(第二个示例)中,它只是一个实现了一些额外功能的包装类(
    insertAtBegin()
    insertAtPlace()
    insertAtLast()

    拥有两个类有几个原因:

    • 要区分列表和单个节点的概念
    • 为了避免从每个方法返回头部节点时出现尴尬的情况
    • 为了避免让类的客户端负责跟踪头节点
    • 为了隐藏实现细节,以便更容易地用等效类替换该类
    • 等等

    它用于包含根/头节点。您还可以把它放在哪里?在您的示例中,
    insertaplace
    insertaplast
    也必须返回列表的开头,否则它不会适用于所有情况。java不是按引用传递对象吗,那么它不会自动更新吗?
    拥有包含根或头的第二个类的概念仅用于OOP目的或其他目的?
    仅用于OOP目的。这取决于数据结构。树节点是树,但链表节点不是链表。
    但没有什么能阻止您在列表的任何节点上调用它
    我在思考时错过了非常重要的一点。