使用“分而治之”在 Java 中进行排序

Posted

技术标签:

【中文标题】使用“分而治之”在 Java 中进行排序【英文标题】:Sorting in Java with "Divide and Conquer" 【发布时间】:2017-06-28 07:22:03 【问题描述】:

合并排序,将一个随机数组分成两半,然后按数字顺序排列。概念被称为“分而治之”。输出有问题,我看不出这段代码有什么问题。 Main 只输出数组中的所有数字。仅供参考,代码的其他部分不是问题。但如果你需要它,我可以给你。

private void merge(int[] a, int first, int mid, int last)

    int size = last - first + 1;
    int [] temp = new int[size];
    int i = first, j = mid + 1;
    for(int s = 0; s < size; s++) // a.length
        if(i > mid) // case a
            temp[s] = a[j];
            j++;
        else if(j > last) // case b
            temp[s] = a[i];
            i++;
        else if(a[i] < a[j]) // case c
            temp[s] = a[i];
            i++;
        else if(a[j] <= a[i]) // case d
            temp[s] = a[j];
            j++;
        
    

    for(int s = first; s < size; s++)
        a[first] = temp[s - first];
    


public void mergeSort(int[] a, int first, int last)

    int size = last - first + 1, mid;
    if(size == 1)
        steps++;
    else if(size == 2)
        if(a[last] > a[first])
            int temp = a[last];
            a[last] = a[first];
            a[first] = temp;
            steps += 3;
        
    else
        mid = (last + first) / 2;
        mergeSort(a, first, mid);
        mergeSort(a, mid + 1, last);
        merge(a, first, mid, last);
        steps += 4;
    

这是生成器的样子:

private void fillArray(int numInts, int largestInt)

    myArray = new int[numInts];
    Random randGen = new Random();

    for(int loop = 0; loop < myArray.length; loop++)
        myArray[loop] = randGen.nextInt(largestInt) + 1;
    

【问题讨论】:

您是否尝试过使用调试器?对于此类问题,您并不总是能够依赖 SO。 @TimBiegeleisen 是的,我使用了调试器。 @StackOver - 为什么不在 merge() 中将 if 和副本从 a[] 更改为 temp[] 以按照您想要的顺序排序到 temp,然后将 for 循环更改为使用 a[s] = temp[s]; ? mergesort() 中的代码按降序对大小为 2 的子数组进行排序,而在 mergesort() 中的代码似乎按升序排序。您需要使它们相同(升序或降序)。 @StackOver - divide and conquer - 在重复除法产生大小为 1 或 2 的子数组之前不会进行排序,然后是 merge() 的第一个实例。 【参考方案1】:

你的代码有两个缺陷:

第一:

for(int s = first; s - first < size; s++)// replace s<size with s-first<size
        a[s] = temp[s - first];//yours a[first] = temp[s-first] 

在您的编码中,first 是固定的,它总是会更新我认为不是您想要的 a[first]。

秒:

....
else if(a[i] > a[j]) // case c  yours a[i]<a[j]
            temp[s] = a[i];
            i++;
else if(a[i] <= a[j]) // case d  yours a[j] <= a[i]
            temp[s] = a[j];
            j++;

.... 

因为关于你的排序,你会得到一个降序,而在合并中你想要升序,这会相互冲突。

【讨论】:

这样做只会给我同样的问题。它不会将随机数组按数字顺序排列。不过谢谢。 @Stack Over 我给你修好了,它可以把随机数组按数字顺序排列。评论是你的代码,我已经修复了它们。 @Stack Over 给我你的意见。 此方法生成随机数,具体取决于您希望数组中有多少数字 (numInts) 以及您希望它达到的最大 int (largestInt)。私人无效fillArray(int numInts,int最大Int)myArray = new int[numInts];随机 randGen = new Random(); for(int loop = 0; loop 我已经编辑了我的问题,所以如果很难看到,那么在顶部会更容易。

以上是关于使用“分而治之”在 Java 中进行排序的主要内容,如果未能解决你的问题,请参考以下文章

如何使用多线程分而治之?

使用分而治之找到一个数字到矩阵排序

分而治之的概念

如何在功能性分而治之 Java 算法中实现“分”功能?

快速排序算法

分而治之和快速排序