Java归并排序实现

标签 java mergesort

我正在尝试用Java实现归并排序。该代码对我来说看起来不错,但它返回初始未排序的数组作为输出。我现在正在学习所有基础知识,所以我很难找到错误。

import java.util.Scanner;
class Hacker{
    int[] input=new int[]{2,4,1,6,8,5,3,7};
    int[] left;
    int[] right;
    //int size;
    Scanner scan=new Scanner(System.in);

    public void mergeSort(int[] input){
        if(input.length<2){
            return;
        }
        int mid=input.length/2;
        left=new int[mid];
        right=new int[input.length-mid];
        System.arraycopy(input, 0, left, 0, left.length);
        System.arraycopy(input, mid, right, 0, right.length);
        mergeSort(left);
        mergeSort(right);
        merge(input,left,right);
    }

    public void merge(int[]input,int[]left,int[]right){
        int i=0,j=0,k=0;
        while(i<left.length&&j<right.length){
            if(left[i]<right[j]){
                input[k++]=left[i++];
            }
            else{
                input[k++]=right[j++];
            }
        }
        while(i<left.length){
            input[k++]=left[i++];
        }
        while(j<right.length){
            input[k++]=right[j++];
        }
    }


    public static void main(String args[]){
        Hacker h=new Hacker();

        h.mergeSort(h.input);        
        for(int i=0;i<h.input.length;i++){
            System.out.print(h.input[i]);
        }
    }
}

输出:

24168537

最佳答案

您的问题是您在递归方法中使用实例变量leftrightinput。这意味着所有递归调用都会覆盖这些值。递归需要局部变量,这意味着从方法返回结果。这也意味着这些方法可以是静态的,并使您的代码更加干净。

这是转换为使用局部变量并返回计算结果的代码。我还简化了一些事情。

public class Sorter {
    public static int[] mergeSort(int[] input) {
        if (input.length < 2) {
            return input;
        }
        int mid = input.length / 2;
        int[] left = Arrays.copyOfRange(input, 0, mid);
        int[] right = Arrays.copyOfRange(input, mid, input.length);
        return merge(mergeSort(left), mergeSort(right));
    }

    public static int[] merge(int[] left, int[] right) {
        int i = 0, j = 0, k = 0;
        int[] output = new int[left.length + right.length];
        while (i < left.length && j < right.length) {
            if (left[i] < right[j]) {
                output[k++] = left[i++];
            } else {
                output[k++] = right[j++];
            }
        }
        while (i < left.length) {
            output[k++] = left[i++];
        }
        while (j < right.length) {
            output[k++] = right[j++];
        }
        return output;
    }

    public static void main(String args[]) {
        int[] input = new int[]{2, 4, 1, 6, 8, 5, 3, 7};
        System.out.println(Arrays.toString(Sorter.mergeSort(input)));
    }
}

供您引用,这是一个简化版本,其中结合了两种方法并就地排序,而不是创建新数组。

public void mergeSort(int[] input) {
    if (input.length >= 2) {
        int[] left = copyOfRange(input, 0, input.length / 2);
        int[] right = copyOfRange(input, input.length / 2, input.length);
        mergeSort(left);
        mergeSort(right);
        for (int i = 0, j = 0, k = 0; i < left.length || j < right.length; k++) {
            if (i >= left.length || (j < right.length && left[i] > right[j]))
                input[k] = right[j++];
            else
                input[k] = left[i++];
        }
    }
}

关于Java归并排序实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43197592/

相关文章:

java - 从监听器内将变量传递到构造函数

java - Perf4j 未正确记录

java - 如何让两个不同的端点具有不同的命名空间和相同的 JAXB 类?

java - 通过 new 运算符或某些接口(interface)进行对象分配

algorithm - 结合了 mergeSort 和 heapsort 的算法的运行时间是多少?

c - C中的合并排序实现

c - 为什么在我使用归并排序时,一个额外的元素被添加到我的 void** 数组中?

java - 如何在 Java 中将多个 Map/List/Array 从 API url 传递到 RestController?

c++ - C++ 中的非递归归并排序

java - 为什么归并排序和快速排序操作的顺序会导致第二个操作运行得更快?