简体   繁体   English

链接列表排序问题

[英]Linked List sorting issue

YES, this is a homework project. 是的,这是一个家庭作业项目。 That being said, I'm looking to learn from my mistakes rather than just have someone do it for me. 话虽如此,我希望从错误中吸取教训,而不仅仅是让某人为我做错。

My project is a word frequency list - I accept a text file (or website URL) and count the: 我的项目是一个单词频率列表 - 我接受一个文本文件(或网站URL)并计算:
- Number of unique words, and - 唯一单词的数量,和
- How many times they appear. - 它们出现的次数。

All methods are provided for me except for one: the insert(E word) method, where the argument is a generic type word. 除了一个之外,我提供了所有方法: insert(E word)方法,其中参数是泛型类型的单词。 The word is stored in a Node ( Linked List project ) that also has a 'count' value, which is the value representing the number of times the word appears in the text being read. 该单词存储在节点( 链接列表项目 )中,该节点还具有“计数”值,该值表示单词在正在读取的文本中出现的次数。

What this method has to do is the following: 该方法必须做的是以下内容:

  1. If the argument is already in the list, increment the count of that element. 如果参数已在列表中,则递增该元素的计数。 I have done this part 我做了这个部分
  2. If the argument is not found in the list, append it to the list. 如果在列表中找不到参数,请将其附加到列表中。 I also have done this part. 我也做过这一部分。
  3. sort the list by descending count value. 按降序计数值对列表进行排序 ie highest -> lowest count 3.5. 即最高 - >最低计数3.5。 If two elements have the same count value, they are sorted by the dictionary order of their word. 如果两个元素具有相同的计数值,则它们按其单词的字典顺序排序。

I am VERY unfamiliar with Linked Lists, so as such I am running into a lot of NullPointerExceptions . 我对链接列表非常不熟悉,因此我遇到了很多NullPointerExceptions This is my current insert method: 这是我目前的插入方法:

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

My isSorted() method: 我的isSorted()方法:

public boolean isSorted(){
    for(Node copy = first; copy.next != null; copy = copy.next){
        if (copy.count < copy.next.count){
            return false;
        }
    }
    return true;
}

and last but not least, the part where I'm struggling, the sort 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;
                }
            }
        }
    }

Here is the output of my insert method when called by the classes/methods given to me: 这是我给出的类/方法调用时insert方法的输出:

Elapsed time:0.084
(the,60)
(of,49)
(a,39)
(is,46)
(to,36)
(and,31)
(can,9)
(in,19)
(more,7)
(thing,7)
(violent,3)
(things,3)
(from,9)
(collected,1)
(quotes,1)
(albert,1)
(einstein,2)
(any,2)
(intelligent,1)
(fool,1)
(make,1)
(bigger,1)
(complex,1)
(it,11)
(takes,1)
(touch,1)
(genius,1)
(lot,1)
(courage,1)
(move,1)
(opposite,1)
(direction,1)
(imagination,1)
(important,5)
(than,3)
(knowledge,3)
(gravitation,1)
(not,17)
(responsible,1)
(for,14)
(people,2)
(falling,1)
(love,2)
(i,13)
(want,1)
(know,3)
(god,4)
(s,8)
(thoughts,2)
(rest,2)
(are,11)
(details,2)
(hardest,1)
(world,7)
(understand,3)
(income,1)
(tax,1)
(reality,3)
(merely,1)
(an,7)
(illusion,2)
(albeit,1)
(very,3)
(persistent,2)
(one,12)
(only,7)
(real,1)
(valuable,1)
(intuition,1)
(person,1)
(starts,1)
(live,2)
(when,3)
(he,11)
(outside,1)
(himself,4)
(am,1)
(convinced,1)
(that,14)
(does,5)
(play,2)
(dice,1)
(subtle,1)
(but,8)
(malicious,1)
(weakness,2)
(attitude,1)
(becomes,1)
(character,1)
(never,3)
(think,1)
(future,2)
(comes,1)
(soon,1)
(enough,1)
(eternal,1)
(mystery,1)
(its,4)
(comprehensibility,1)
(sometimes,1)

My initial idea has been to try and loop the if(!isSorted()){ countSort();} part to just repeatedly run until it's sorted, but I seem to run into an infinite loop when doing that. 我最初的想法是尝试循环if(!isSorted()){ countSort();}部分只是重复运行直到它被排序,但我似乎在这样做时遇到无限循环。 I've tried following my professor's lecture notes, but unfortunately he posted the previous lecture's notes twice so I'm at a loss. 我试过跟随我教授的讲义,但不幸的是他两次发布了前一讲的笔记,所以我很茫然。

I'm not sure if it's worth mentioning, but they provided me an iterator with methods hasNext() and next() - how can I use this as well? 我不确定它是否值得一提,但它们为我提供了一个方法hasNext()next()的迭代器 - 我怎么能用它? I can't imagine they'd provide it if it were useless. 我无法想象如果它没用就会提供它。

Where am I going wrong? 我哪里错了?

You are close. 你很亲密 First the function to compare the items is not complete, so isSorted() could yield wrong results (if the count is the same but the words are in wrong order). 首先,比较项目的功能不完整,因此isSorted()可能会产生错误的结果(如果计数相同但单词的顺序错误)。 This is also used to sort, so it's best to extract a method for the comparison: 这也用于排序,因此最好提取一个比较方法:

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

Or simplified which is enough in your case: 或简化,在您的情况下足够:

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

For the sort you seem to have chosen bubble sort, but you are missing the outer part: 对于您似乎选择冒泡排序的排序,但您缺少外部部分:

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

We could use the help of Java native library implementation or more efficient sort algorithms, but judging from the exercise the performance of the sort algorithm is of no concern yet, first need to grasp basic concepts. 我们可以使用Java本机库实现的帮助或更有效的排序算法,但从练习来看,排序算法的性能尚无关注,首先需要掌握基本概念。

With looking your codes, it sounds like to me that two things can be done: 通过查看代码,我觉得可以做两件事:

Firstly, you can make use of Comparable class method. 首先,您可以使用Comparable类方法。 So, I assume you wrote the class Node, thus you may want to inherit from Comparable class. 所以,我假设您编写了Node类,因此您可能希望继承Comparable类。 When you inherited from that class, java will automatically provide you the compareTo method, and all you need to do is to specify in that method that "I want to compare according to your counts and I want it to be in ascending order." 从该类继承时,java会自动为您提供compareTo方法,您需要做的就是在该方法中指定“我想根据您的计数进行比较,并希望它按升序排列”。 **Edit(1):By the way, I forgot the mention before but after you impelement your compareTo method, you can use Collections.sort(LinkedList list), and it will be done. **编辑(1):顺便说一句,我之前忘记了提及但是在你对compareTo方法进行了修改之后,你可以使用Collections.sort(LinkedList list),它就完成了。

The second solution came to mind is that you can sort your list during the countSort() operation with the technique of adding all to an another list with sorting and after add all them back to the real list. 第二个解决方案是您可以在countSort()操作期间对列表进行排序,其方法是将所有列表添加到另一个带有排序的列表中,然后将它们全部添加回真实列表。 The sorting technique I'm trying to say is, keep going towards to the end of the list until you find a Node in the list that has a count smaller than currently adding Node's counts. 我想说的排序技术是,一直走到列表的末尾,直到你在列表中找到一个小于当前添加节点计数的节点。 Hope that doesn't confuse your head, but by this way you can achieve more clear method and less complicated view. 希望不要混淆你的头脑,但通过这种方式你可以实现更清晰的方法和更简单的视图。 To be clear I want to repeat the procedure: 要明确我想重复这个程序:

Look the next 看下一个
If (next is null), add it //You are at the end. 如果(下一个为空),添加它//你就在最后。
else{ 其他{
if (count is smaller than current count), add it there if(count小于当前计数),将其添加到那里
else, keep moving to the next Node. 否则,继续移动到下一个节点。 //while can be used for that. //虽然可以用于此。
} }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM