Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 链表排序问题_Java_List_Sorting - Fatal编程技术网

Java 链表排序问题

Java 链表排序问题,java,list,sorting,Java,List,Sorting,是的,这是一个家庭作业项目。 也就是说,我希望从我的错误中吸取教训,而不仅仅是让别人帮我 我的项目是一个词频列表-我接受一个文本文件(或网站URL)并计算: -唯一字数,和 -它们出现了多少次 所有方法都为我提供,只有一个除外:insert(E-word)方法,其中参数是泛型词。 单词存储在一个节点(链表项目)中,该节点也有一个“count”值,该值表示单词在正在读取的文本中出现的次数 此方法必须执行以下操作: 如果参数已经在列表中,则增加该元素的计数。我已经完成了这部分 如果在列表中找不到参数

是的,这是一个家庭作业项目。 也就是说,我希望从我的错误中吸取教训,而不仅仅是让别人帮我

我的项目是一个词频列表-我接受一个文本文件(或网站URL)并计算:
-唯一字数,和
-它们出现了多少次

所有方法都为我提供,只有一个除外:
insert(E-word)
方法,其中参数是泛型词。 单词存储在一个节点(链表项目)中,该节点也有一个“count”值,该值表示单词在正在读取的文本中出现的次数

此方法必须执行以下操作:

  • 如果参数已经在列表中,则增加该元素的计数。我已经完成了这部分
  • 如果在列表中找不到参数,请将其附加到列表中。我也做了这部分
  • 通过递减计数值对列表进行排序。i、 e.最高->最低计数 3.5. 如果两个元素具有相同的计数值,则按其单词的字典顺序进行排序 我对链表非常不熟悉,因此我遇到了很多
    NullPointerExceptions
    。这是我当前的插入方法:

    public void insert(E word){
        if(word.equals("")){
            return;
        }
    
        if(first == null){//if list is null (no elements)
            /*Node item = new Node(word);
            first = item;*/
            first = new Node(word);
        }
    
        else{//first != null
    
            Node itemToAdd = new Node(word);
    
            boolean inList = false;
    
            for(Node x = first; x != null; x=x.next){
                if (x.key.equals(word)){// if word is found in list
                    x.count++;//incr
                    inList = true;//found in list
    
                    break;//get out of for
                }//end IF
                if(x.next == null && inList == false){//if end of list && not found
                    x.next = itemToAdd;//add to end of list
                    break;
                }//end IF
            }//end FOR
    
            //EVERYTHING ABOVE THIS LINE WORKS. 
            if (!isSorted()){
                countSort();
            }
    
        }//end ELSE
    }//end method
    
    public void countSort(){
    
            for (Node x = first, p = x.next; p != null; x=x.next, p=p.next){
                // x will start at the first Node, P will always be 1 node ahead of X.
    
                if(x == first && (x.count < p.count)){
                    Node oldfirst = first; 
                    x.next = p.next;
                    first = p;
                    first.next = oldfirst;
                    break;
                }
    
                if (x.count < p.count){
                    //copy.next == x.
                    Node oldfirst = first;
                    oldfirst.next = first.next; 
                    x.next = p.next;
                    first = p;
                    first.next = oldfirst;
                    break;
                }
    
                if (x.count == p.count){
                    if(x.toString().charAt(0) < p.toString().charAt(0)){
                        //[x]->[p]->[q]
    
                        Node oldfirst = first;
                        x.next = p.next;
                        first = p;
                        first.next = oldfirst;
                        break;
                    }
                }
            }
        }
    
    我的
    isSorted()
    方法:

    public boolean isSorted(){
        for(Node copy = first; copy.next != null; copy = copy.next){
            if (copy.count < copy.next.count){
                return false;
            }
        }
        return true;
    }
    
    我最初的想法是尝试循环
    if(!isSorted()){countSort();}
    部分,直到它被排序为止,但我在这样做时似乎遇到了一个无限循环。我试着听教授的讲稿,但不幸的是,他把上一堂课的讲稿贴了两遍,所以我不知所措

    我不确定这是否值得一提,但他们为我提供了一个迭代器,其中包含方法
    hasNext()
    next()
    ——我如何使用它呢?我无法想象他们会提供它,如果它是无用的


    我哪里出错了?

    你很接近。首先,比较项目的函数不完整,因此
    isSorted()
    可能会产生错误的结果(如果计数相同,但单词顺序错误)。这也用于排序,因此最好提取一种方法进行比较:

    // returns a value < 0 if a < b, a value > 0 if a > b and 0 if a == b
    public int compare(Node a, Node b) {
        if (a.count == b.count)
            return a.word.compareTo(b.word);
            // case-insensitive: a.word.toLoweCase().compareTo(b.word.toLowerCase())
        } else {
            return a.count - b.count;
        }
    }
    

    我们可以借助Java本机库实现或更高效的排序算法,但从练习中判断,排序算法的性能还不重要,首先需要掌握基本概念。

    通过查看代码,我觉得有两件事可以做到:

    首先,您可以使用可比较类方法。所以,我假设您编写了类节点,因此您可能希望从可比较的类继承。当您从该类继承时,java将自动为您提供compareTo方法,您需要做的只是在该方法中指定“我希望根据您的计数进行比较,并且我希望它按升序排列。” **编辑(1):顺便说一句,我忘记了之前提到的内容,但是在您将compareTo方法推进之后,您可以使用Collections.sort(LinkedList列表),它将被完成

    想到的第二个解决方案是,您可以在countSort()操作期间对列表进行排序,方法是通过排序将所有列表添加到另一个列表中,然后将所有列表重新添加到真实列表中。我想说的排序技术是,一直到列表的末尾,直到在列表中找到一个节点,该节点的计数小于当前添加节点的计数。希望这不会让你头脑混乱,但通过这种方式,你可以获得更清晰的方法和更少复杂的视图。为了清楚起见,我想重复以下步骤:

    看看下一个
    如果(next为null),则添加它//您位于末尾。
    否则{
    如果(计数小于当前计数),则将其添加到该位置
    否则,继续移动到下一个节点。//while可用于此操作。
    }


    你为什么选择链表?@MaxZoom是他的作业,他说。@MaxZoom-教授让我们用链表来做,因为这是我们目前正在学习的数据结构。暂时注释掉//if(x.count==p.count){..}块,然后尝试先按计数排序。也试试看。将while(!sorted){}放入insert方法。我理解您提供的大部分内容,但如果我能看到完整的实施,是否可能。我理解您对第一个解决方案所说的内容,但我相信我在第二个解决方案中可能不清楚。参数中的所有节点的计数均为1,并且仅出现一次(到目前为止)的节点的值也为1。没有节点的计数值小于参数。此外,我还应用了一个ListIterator类-我的主要类声明是:public类Frequency实现了Iterable,因此如果我理解这一点:E泛型扩展了comparable,而Frequency实现了Iterable(我省略了关于字符排序的部分,因为我认为最好从正确的计数排序开始),并再次受到无限循环的欢迎。我不确定在哪里,但我认为在我的代码中的某个地方,我的引用被弄乱了。希望我调试它时不是100多次迭代。@csh1579我添加了多一点代码来说明我的意思,就像这样,你不应该得到无限循环。现在我遇到了一个棘手的问题在整个项目中,我都很紧张-你说要交换x和p,但是如果我不知道导致x的元素,我怎么能交换x和p?正常的过程不是:link x.next to p.next,link p.next to x,link(指向x的元素)to p?我知道你是如何接近它的,但是我们不需要检查以确保x.next.next不是空的吗(或者我错过了这里的要点:P)?@csh1579也正是我首先想到的,但通常检查为x!=null,因为它将在x=x之后进行检查。下一步,因此它与冒泡排序一样正确。oldX==null是唯一的特例。
    // returns a value < 0 if a < b, a value > 0 if a > b and 0 if a == b
    public int compare(Node a, Node b) {
        if (a.count == b.count)
            return a.word.compareTo(b.word);
            // case-insensitive: a.word.toLoweCase().compareTo(b.word.toLowerCase())
        } else {
            return a.count - b.count;
        }
    }
    
    public boolean correctOrder(Node a, Node b) {
        if (a.count > b.count)
           return true;
        else if (a.count < b.count)
           return false;
        else
           return a.word.compareTo(b.word) <= 0;
    }
    
    boolean change;
    do {
       change = false;
       Node oldX = null;
       // your for:
       for (Node x = first; x.next != null; x = x.next) {
           if (!correctOrder(x, x.next)) {
                // swap x and x.next, if oldX == null then x == first
                change = true;
           }
           oldX = x;
       }
    } while (change);