java - 合并排序错误的输出

标签 java algorithm sorting debugging mergesort

我的 Java 合并排序代码有两个问题。

  1. 当我输入数组 [3,4,2,1,0,6,8] 时,我得到输出 [0, 1, 2, 3, 4, 6, 0],它显然是错误的。

  2. 我怀疑我编写代码的方式并不尽如人意。如果您能找到任何改进,请告诉我。我知道网络上已经有大量的合并排序算法,但我特别询问我编写代码的方式。谢谢!

    import java.util.Arrays;
    
    public class Main {
    
        static int[] mergeSort(int[] arr) {
    
            if (arr == null)
                return null;
    
            if (arr.length <= 1)
                return arr;
    
            int length = arr.length;
            int mid = arr.length / 2;
    
            int[] left = Arrays.copyOfRange(arr, 0, mid);
            int[] right = Arrays.copyOfRange(arr, mid, length);
    
            int[] sortedLeft = mergeSort(left);
            int[] sortedRight = mergeSort(right);
    
            int leftSmallestIndex = 0;
            int rightSmallestIndex = 0;
    
            int leftLength = left.length;
            int rightLength = right.length;
    
            int[] sortedArr = new int[length];
    
            outer: for (int i = 0; i < length; i++) {
                if (leftSmallestIndex >= leftLength) {
                    while (rightSmallestIndex < rightLength) {
                        sortedArr[i] = sortedRight[rightSmallestIndex];
                        rightSmallestIndex++;
                        break outer;
                    }
                }
                if (rightSmallestIndex >= rightLength) {
                    while (leftSmallestIndex < leftLength) {
                        sortedArr[i] = sortedLeft[leftSmallestIndex];
                        leftSmallestIndex++;
                        break outer;
                    }
                }
                if (sortedLeft[leftSmallestIndex] < sortedRight[rightSmallestIndex]) {
                    sortedArr[i] = sortedLeft[leftSmallestIndex];
                    leftSmallestIndex++;
                }
                else {
                    sortedArr[i] = sortedRight[rightSmallestIndex];
                    rightSmallestIndex++;
                }
            }
    
            return sortedArr;
    
        }
    
        public static void main(String[] args) {
        // write your code here
            int[] a = new int[] {3,4,2,1,0,6,8};
            System.out.println(Arrays.toString(mergeSort(a)));
        }
    }
    

最佳答案

您的声明break outer;实际上是导致控件退出 for 循环,它不会继续 for 循环(我猜你正试图继续 for 循环,使用那个 break outer; 语句)。

这会导致循环只更新 sortedRight 中的一个剩余元素或 sortedLeft进入排序数组而其他人错过了,这导致了 0在循环结束时。

你实际上不需要这样做,你可以循环直到 - leftSmallestIndex < leftLength && rightSmallestIndex < rightLength然后执行您在 for 循环内部和外部定义的 while 循环。

例子-

import java.util.*;
import java.math.*;
class a {
    static int[] mergeSort(int[] arr) {

        if (arr == null)
            return null;

        if (arr.length <= 1)
            return arr;

        int length = arr.length;
        int mid = length / 2;

        int[] left = Arrays.copyOfRange(arr, 0, mid);
        int[] right = Arrays.copyOfRange(arr, mid, length);

        int[] sortedLeft = mergeSort(left);
        int[] sortedRight = mergeSort(right);

        int leftSmallestIndex = 0;
        int rightSmallestIndex = 0;

        int leftLength = left.length;
        int rightLength = right.length;

        int[] sortedArr = new int[length];
        int i = 0;
        for (; leftSmallestIndex < leftLength && rightSmallestIndex < rightLength;i++) {
            if (sortedLeft[leftSmallestIndex] < sortedRight[rightSmallestIndex]) {
                sortedArr[i] = sortedLeft[leftSmallestIndex];
                leftSmallestIndex++;
            }
            else {
                sortedArr[i] = sortedRight[rightSmallestIndex];
                rightSmallestIndex++;
            }
        }
        while (rightSmallestIndex < rightLength) {
            sortedArr[i] = sortedRight[rightSmallestIndex];
            rightSmallestIndex++;
            i++;
        }
        while (leftSmallestIndex < leftLength) {
           sortedArr[i] = sortedLeft[leftSmallestIndex];
           leftSmallestIndex++;
           i++;
        }
        return sortedArr;

    }
    public static void main(String[] args) {
     int[] a = new int[] {3,4,2,1,0,6,8};
        System.out.println(Arrays.toString(mergeSort(a)));
        outer : for(int i = 0;i < 10 ; i++) {
        while(true) {
            System.out.println(i);
            break outer;
        }
    }
    }
}

最后,我添加了示例(您尝试使用 break outer; 的简单版本,它应该可以帮助您了解正在发生的事情)。

关于java - 合并排序错误的输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31397522/

相关文章:

java - itext5 在上下文中签署图像

python - 算法:将向量添加到列表中同时避免嵌套

algorithm - 计算无反边图的最小割

algorithm - 给定整数迭代器的正迭代器设计

c - Valgrind 报告排序算法分区函数的堆栈溢出 : can't figure out why

php - 按列名排序在列表页面上的纯 PHP 中不起作用

java - 在哪里可以找到使用模式的任务

java - HTTP 代理 Servlet 错误

java - 使用 Hibernate、Postgres 和 Guice Provider 时“事务中空闲”

Django 检查 2 个模型字段的重复项