簡體   English   中英

Java中的字符串合並排序 - 鏈接列表

[英]Merge Sort on Strings in Java - Linked List

我有一個練習,我必須在鏈接列表中插入一個字符串。 假設字符串如下:

"Java Coding Is Great"

合並排序后,鏈表應該看起來像這樣:

coding >>> great >>> is >>> java.

問題是在我的Merge Sort代碼中我收到以下信息:

 great >> is >> java >> coding 

所有的單詞都排序但是第一個字(原始列表的頭部)不是。

我有兩個類:TextList和WordNode。

WordNode類有兩個屬性:

String _word; WordNode _next; //an address to the next link

TextList類只有一個屬性:鏈表頭部的地址:

WordNode _head;

我有一個構造函數,我將String隨機插入到鏈表中。 最后它開始合並sotring列表。 這個算法是為了這個練習。

public TextList(String text){
     String s=""; int index=text.length();
    //we will stop at the end of the String.
    for (int i=text.length()-1; i>=0; i--){
        //if we reached a space, insert each string in appropriate order, 
        //the first word is the head of the string and last word points to null.
        if (!(text.charAt(i)>='a' && text.charAt(i)<='z')){ 
            s=text.substring(i,index);
            _head=new WordNode(s,_head);
            s="";
            index=i;
        }
        if (i==1){
            s=text.substring(i-1,index);
            _head=new WordNode(s,_head);
        }
    }

//start merge sotring the list.
    this._head=this._head.mergeSort();
}

合並排序方法:mergeSort,merge和split :(這些在WordNode類中):

合並排序方法

public WordNode mergeSort(){
    return mergeSort(this);
}
private WordNode mergeSort(WordNode h){
    // Sort h by recursively splitting and merging
    if (h==null || h._next==null)
        return h;
    else{
        WordNode evens=h.splitOdds();
        WordNode odds=h.splitEvens();
        return mergeSort(odds).merge(mergeSort(evens)); 
    }
}

合並方法

private WordNode merge(WordNode h){
        //method merges this's list with h's list

        //if h is null, just return this.
        if (h==null){
            return this;
        }
        if (this._word.compareTo(h._word)<0){
            if (this._next==null)
                return new WordNode(this._word,h);
            else
                return new WordNode(this._word,this._next.merge(h));
        }
        else
            return new WordNode (h._word, merge(h._next));

    }

拆分方法:一個用於偶數位置,一個用於奇數位置。

private WordNode splitOdds(){
    boolean flag=true;
    WordNode odds=null;
    WordNode ptr=this;
    while (ptr!=null){  
        if(flag)
        odds=new WordNode(ptr._word,odds);
        ptr=ptr.getNext();
        flag=!flag;
    }
    return odds;
}
//MUST BE INITILIZED ON HEAD
    private WordNode splitEvens(){
        boolean flag=true;
        WordNode evens=null;
        WordNode ptr=this._next;
        while (ptr!=null){
            if (flag)
                evens=new WordNode(ptr._word,evens);
                ptr=ptr.getNext();
                flag=!flag;
            }



        return evens;
    }

請幫我弄清楚什么是錯的。 不幸的是,我不能使用第三類我不能使用指針列表的開頭或列表的末尾。

您可以使用調試器單步執行代碼嗎? 這將有助於您找出問題所在。 即使是一些明智的斷點也會有所幫助。

從僅包含單個條目的列表開始:“Java”。 走着瞧吧。

然后嘗試兩個條目列表:“Java編碼”。 看看那種情況會發生什么。

弄清楚簡單情況下發生的事情,然后處理更復雜的情況。

這里的問題有點好笑。

在我的構造函數中,我已經將每個單詞插入到我的列表中。

我修復了這個代碼:

            s=text.substring(i+1,index);

代替:

            s=text.substring(i,index);

來自DevForum的NormR可以獲得答案。

很好,但我不喜歡你在WordNode中的merge()解決方案。 一方面,您可以比較您喜歡的每個節點:

this._word.compareTo(h._word);

但是在那種情況下merge()和split()都是私有的,所以我認為更好的方法是將它們放入TextList和mergeSort()而不會重載。 您需要在添加節點時對鏈接列表中的所有節點進行排序,而不僅僅是其中的一部分。 這就是為什么這個

this._head = this._head.mergeSort();

和這個

public WordNode mergeSort(){
    return mergeSort(this);
}

在WordNode中看起來毫無用處。
另一方面,如果您將對mergeSort的調用放入TextList中,就像這樣

this._head = this.mergeSort(this._head);

並在TextList中合並到這一個

 public WordNode mergeSort(WordNode n){

 }

它已經更好但是你可以做得更好,通過減少更多的時間和空間復雜性的方式將你的列表分成幾率和這樣的平均值

int counter = 1;    //  nodes counter helps to know if the current node is odd or even
WordNode L = null,  //  odd nodes
         R = null;  //  even nodes
while(h != null)
{
    if(counter%2 == 0)
        R = new WordNode(h.getWord(), R, h.getWordCounter());
    else
        L = new WordNode(h.getWord(), L, h.getWordCounter());
    //  
    h = h.getNext();
    counter++;
}

當你把它放在一起時你得到這樣的東西(不要忘記單詞計數器)

public WordNode mergeSort(WordNode h){
    int counter = 1;    //  nodes counter helps to know if the current node is odd or even
    WordNode L = null,  //  odd nodes
             R = null;  //  even nodes
    while(h != null)
    {
        if(counter%2 == 0)
            R = new WordNode(h.getWord(), R, h.getWordCounter());
        else
            L = new WordNode(h.getWord(), L, h.getWordCounter());
        //  
        h = h.getNext();
        counter++;
    }
    return merge(mergeSort(L), (mergeSort(R)));
}

現在剩下的就是像這樣完成merge()並再次不要忘記單詞計數器

private WordNode merge(WordNode L, WordNode R)
{   
    while(L != null || R != null)
    {
        if(L != null && R != null)
            if(L.getWord().compareTo(R.getWord()) <= 0)
                return new WordNode(L.getWord(), merge(L.getNext(), R), L.getWordCounter());
            else
                return new WordNode(R.getWord(), merge(L, R.getNext()), R.getWordCounter());
        else if(L != null)
            return new WordNode(L.getWord(), merge(L.getNext(), R), L.getWordCounter());
        else if(R != null)
            return new WordNode(R.getWord(), merge(L, R.getNext()), R.getWordCounter());
    }
    return null;
}

向教授Rosenstein問好;-)

暫無
暫無

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

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