在Java中合并排序实现问题

时间:2017-04-01 23:24:13

标签: java algorithm sorting mergesort sentinel

我在算法课程中学习合并排序。我们的教授建议我们尝试实现本书中提供的伪代码。

  1. 我在使用Integer.MAX_VALUE作为标记值时是否正确 排序整数数组(用于Merge中的第8行和第9行) 方法伪代码如下)?
  2. 对于Merge-Sort伪代码方法的第2行,使用Math.ceil()编写Java代码是否正确? (编辑:它实际上是地板,我更新了我的代码以反映这一点。)
  3. 如果您发现任何其他错误,请告诉我们!

    这是本书为合并排序提供的伪代码。 merge sort algorithm part 1

    merge sort algorithm part 2

    而且,这是我用Java编写代码的方式:

    public void mergeSort(int[] arrNums, int p, int r) {
        if (p < r) {
            int q = (p + r) / 2;
            mergeSort(arrNums, p, q);
            mergeSort(arrNums, q + 1, r);
            merge(arrNums, p, q, r);
        }
    }
    
    public void merge(int[] arrNums, int p, int q, int r) {
        int nOne = q - p + 1;
        int nTwo = r - q;
    
        int[] arrLeft = new int[nOne + 1];
        int[] arrRight = new int[nTwo + 1];
    
        for (int i = 0; i < nOne; i++) {
            arrLeft[i] = arrNums[p + i - 1];
        }
    
        for (int j = 0; j < nTwo; j++) {
            arrRight[j] = arrNums[q + j];
        }
    
        arrLeft[nOne] = Integer.MAX_VALUE;
        arrRight[nTwo] = Integer.MAX_VALUE;
    
        // Tracks arrLeft index
        int i = 0;
    
        // Tracks arrRight index
        int j = 0;
    
        for (int k = p; k < r; k++) {
            if (arrLeft[i] <= arrRight[j]) {
                arrNums[k] = arrLeft[i];
                i++;
            } else {
                arrNums[k] = arrRight[j];
                j++;
            }
        }
    }
    

2 个答案:

答案 0 :(得分:1)

for方法中的最后一个merge循环,变量k应该从p - 1开始:

for (int k = p - 1; k < r; k++) {
    if (arrLeft[i] <= arrRight[j]) {
        arrNums[k] = arrLeft[i];
        i++;
    } else {
        arrNums[k] = arrRight[j];
        j++;
    }
}

许多教科书中的伪代码都喜欢从1开始数组索引,因此您需要将其减去1.

答案 1 :(得分:0)

如果有人对此感兴趣,我会在几天前实施它。

private static void mergeSort(double[] arr, int start, int end){
    if(start < end){
        int mid = ( start + end ) / 2;
        mergeSort(arr, start, mid);
        mergeSort(arr, mid + 1, end);
        Merge(arr, start, mid, end);
    }
}


private static void Merge(double[] arr, int start, int mid, int end){

    double[] leftArray = new double[mid - start + 2];
    double[] rightArray = new double[end - mid + 1];
    for(int i = start; i <= mid; i++ )
        leftArray[i - start] = arr[i];
    for (int i = mid + 1; i <= end; i++ )
        rightArray[i - mid - 1] = arr[i];

    leftArray[mid - start + 1] = Double.POSITIVE_INFINITY;
    rightArray[end - mid] = Double.POSITIVE_INFINITY;

    int leftIndex = 0, rightIndex = 0;

    for (int k = start; k <= end; k++){
        if(leftArray[leftIndex] <= rightArray[rightIndex])
            arr[k] = leftArray[leftIndex++];
        else
            arr[k] = rightArray[rightIndex++];
    }   
}