簡體   English   中英

鏈接列表排序問題

[英]Linked List sorting issue

是的,這是一個家庭作業項目。 話雖如此,我希望從錯誤中吸取教訓,而不僅僅是讓某人為我做錯。

我的項目是一個單詞頻率列表 - 我接受一個文本文件(或網站URL)並計算:
- 唯一單詞的數量,和
- 它們出現的次數。

除了一個之外,我提供了所有方法: insert(E word)方法,其中參數是泛型類型的單詞。 該單詞存儲在節點( 鏈接列表項目 )中,該節點還具有“計數”值,該值表示單詞在正在讀取的文本中出現的次數。

該方法必須做的是以下內容:

  1. 如果參數已在列表中,則遞增該元素的計數。 我做了這個部分
  2. 如果在列表中找不到參數,請將其附加到列表中。 我也做過這一部分。
  3. 按降序計數值對列表進行排序 即最高 - >最低計數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

我的isSorted()方法:

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

最后但並非最不重要的是,我正在努力的部分,排序方法:

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

這是我給出的類/方法調用時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)

我最初的想法是嘗試循環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;
    }
}

或簡化,在您的情況下足夠:

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

我們可以使用Java本機庫實現的幫助或更有效的排序算法,但從練習來看,排序算法的性能尚無關注,首先需要掌握基本概念。

通過查看代碼,我覺得可以做兩件事:

首先,您可以使用Comparable類方法。 所以,我假設您編寫了Node類,因此您可能希望繼承Comparable類。 從該類繼承時,java會自動為您提供compareTo方法,您需要做的就是在該方法中指定“我想根據您的計數進行比較,並希望它按升序排列”。 **編輯(1):順便說一句,我之前忘記了提及但是在你對compareTo方法進行了修改之后,你可以使用Collections.sort(LinkedList list),它就完成了。

第二個解決方案是您可以在countSort()操作期間對列表進行排序,其方法是將所有列表添加到另一個帶有排序的列表中,然后將它們全部添加回真實列表。 我想說的排序技術是,一直走到列表的末尾,直到你在列表中找到一個小於當前添加節點計數的節點。 希望不要混淆你的頭腦,但通過這種方式你可以實現更清晰的方法和更簡單的視圖。 要明確我想重復這個程序:

看下一個
如果(下一個為空),添加它//你就在最后。
其他{
if(count小於當前計數),將其添加到那里
否則,繼續移動到下一個節點。 //雖然可以用於此。
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM