2013-03-26 114 views
1

我一直在努力合併排序遞歸代碼,我碰到了一個減速帶。我已經通過互聯網和我的算法本身在紙上多次,我似乎無法弄清楚這個問題。遞歸合併排序Java程序

public static int[] mergesort(int[] data, int low, int high) 
    { 
     int middle = (high+low)/2; 
     if (middle==low) 
     { 
      int[] data2 = new int [1]; 
      data2[0]=data[middle]; 
      return data2; 
     } 
     else 
     { 
      int[] firstHalfSorted = mergesort(data, low, middle); 
      int[] secondHalfSorted = mergesort(data, middle+1, high); 
      return (merge(firstHalfSorted, secondHalfSorted)); 
     } 
    } 

    public static int[] merge(int[] firstHalfSorted, int[] secondHalfSorted) 
    { 
     int[] SortedArray = new int[firstHalfSorted.length+secondHalfSorted.length]; 
     int m = 0; 
     int n = 0; 
     int count = 0; 
     while (m<firstHalfSorted.length && n<secondHalfSorted.length) 
     { 
      if (firstHalfSorted[m]>secondHalfSorted[n]) 
      { 
       SortedArray[count]=secondHalfSorted[n]; 
       count++; 
       n++; 
      } 
      else if (firstHalfSorted[m]<secondHalfSorted[n]) 
      { 
       SortedArray[count]=firstHalfSorted[m]; 
       count++; 
       m++; 
      } 
     } 
     if (m!=firstHalfSorted.length) 
     { 
      while(m<firstHalfSorted.length){ 
       SortedArray[count]=firstHalfSorted[m]; 
       count++; 
       m++; 
      } 
     } 
     if (n!=secondHalfSorted.length) 
     { 
      while(n<secondHalfSorted.length){ 
       SortedArray[count]=secondHalfSorted[n]; 
       count++; 
       n++; 
      } 
     } 
     return SortedArray; 
    } 

有代碼。問題出在一個文本輸入文件中,數字爲3,9,7,2,10,5,1,8,代碼只對每個其他數字排序,分別是3,7和10,1,然後是3, 7,1,10。

按我所有的想法,它應該排序3,9然後7,2等,然後,3,9,7,2和10,5,1,8等等,但它不!你們能幫我出去嗎?

+0

你歸併方法看起來不一樣/錯誤 – smk 2013-03-26 05:00:38

+0

任何關於我能做什麼想法? – 2013-03-26 05:18:46

+0

請只發布相關的代碼。在我看來,你對文件I/O沒有問題。然後,只需在代碼中初始化示例數組,並從代碼示例中刪除不相關的文件讀/寫代碼。不相關的代碼只是表明你不願意付出任何努力來解決你的問題。 – 2013-03-26 05:29:39

回答

4

據我所知,有問題的代碼是:

if (middle==low) 
{ 
    int[] data2 = new int [1]; 
    data2[0]=data[middle]; 
    return data2; 
} 

該代碼將返回一個元件陣列時high-low<=1。因此,對於low = 0, high=1方法,當它期望返回排序的兩元素數組時,將返回第零個元素。你可以把它改成:

if(low==high) //one element passed 
//same here 
+0

我們走吧!可愛!非常感謝! – 2013-03-26 05:44:49

+0

@MarcHosang很高興聽到這一點。如果您發現此答案有幫助,請考慮接受它(答案左側有一個複選框)。看看這個[faq](http://stackoverflow.com/faq#howtoask)。 – 2013-03-26 05:49:01

0

對於合併排序,您只需要將數據分爲兩部分,在這兩部分遞歸,然後合併。與其試圖通過查找中間數據或您嘗試執行的任何操作來劃分數據,而不是將整個列表分成兩半。

例如:

private int[] mergesort(int[] data) { 
    int[] half1 = new int[data.length/2]; 
    int[] half2 = new int[(data.length % 2 == 0)? data.length/2 : data.length/2 + 1]; 
    for (int i = 0; 2 * i < data.length; i++) { 
     half2[i] = data[2 * i]; 
     if (2 * i + 1 < data.length) half1[i] = data[2 * i + 1]; 
    } 
    int[] firstHalfSorted = mergesort(half1); 
    int[] secondHalfSorted = mergesort(half2); 
    return merge(firstHalfSorted, secondHalfSorted); 
} 

如果你想保持當前的方法(這實際上看起來像它應該工作),你只需要通過改變if (middle == low)if (high == low)修復整數除法錯誤。

+0

嗯,我希望找到中間,然後在那裏分割它,然後重複每個合併排序實例,直到它們剩下一對,然後對每個實例進行排序。 – 2013-03-26 05:27:52

+0

我想我明白你要去哪裏了。也許你的問題是整數除法。如果低位和高位相距1,則第一種情況會發生,這會失去您想考慮的其他元素。相反,我會改變你的支票是:'if(data.length == 1)' – 2013-03-26 05:37:49

+0

嗯,第一個回報是預期的3,但是我希望中間值+ 1變低,然後低+成爲另一個價值。 例如,2 + 3/2 = 2 然後2 + 1 + 3/2 = 3 – 2013-03-26 05:39:12

1

你必須在這裏更改以下兩件事情:

1)改變if (middle==low)if (high==low)在以前的帖子指出。

2)將else if (firstHalfSorted[m] **<** secondHalfSorted[n])更改爲else if (firstHalfSorted[m] **<=** secondHalfSorted[n])或簡單地else

第二點很重要,因爲目前您的代碼不支持重複的數字。換句話說,你的if-else不是窮盡的,因爲他們不認爲firstHalfSorted[m]secondHalfSorted[n]都是相等的情況。

0

這是一個簡單的合併排序代碼與遞歸。

public class solution { 

public static void merge(int[] input, int s, int e){ 

    int m = (s + e)/2; 

    int temp[] = new int[e - s + 1]; 

    int s1 = s; 
    int s2 = m + 1; 

    int i = s1; 
    int j = s2; 
    int p = 0; 
    while(i <= m && j <= e){ 
     if(input[i] > input[j]){ 
      temp[p] = input[j]; 
      j++; 
      p++; 
     }else{ 
      temp[p] = input[i]; 
      i++; 
      p++; 
     } 
    }//end of while loop 

    while(i <= m){ 
      temp[p] = input[i]; 
      p++; 
      i++; 
    } 
    while(j <= e){ 
      temp[p] = input[j]; 
      p++; 
      j++; 
    } 

    for(int k = 0; k < temp.length; k++){ 
     input[s + k] = temp[k]; 
    } 
} 

public static void callsort(int[] input, int s, int e){ 

    if(s >= e){ 
     return ; 
    } 

    int m = (s + e)/2; 

    callsort(input, s, m); 
    callsort(input, m + 1, e); 
    merge(input, s, e); 

} 

public static void mergeSort(int[] input){ 
    callsort(input , 0 , input.length - 1); 
} 
} 

輸入:5 6 3 2 1 4 輸出:1 2 3 4 5 6