2013-03-26 144 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