【问题标题】:I have an issue with implementing Merge Sort for Java我在为 Java 实现合并排序时遇到问题
【发布时间】:2016-08-29 02:58:34
【问题描述】:
public static void main(String[] args) {
    int[] test = {5,4,3,5,7,5,1,5,96};
    System.out.print("Before: ");
    printList(test);
    mergeSort(test, 1, test.length);
    //System.out.print("After:  ");
    //printList(test);
}

public static void printList(int[] test){
    for (int i= 0; i < test.length; i++){
        System.out.print(test[i] + " ");
    }
    System.out.println();
}

public static void merge(int[] A, int p, int q, int r){
    int n1 = q - p + 1;
    int n2 = r - q;

    int[] L = new int[n1];
    int[] R = new int[n2];

    for(int i = 1; i <= n1; i++){
        L[i] = A[p+i-1];
    }
    for (int j = 1; j <= n2; j++){
        R[j] = A[q+j];
    }
    int i = 1;
    int j = 1;

    for (int k=p; i <= r; i++){
        if (i > n1){
            A[k] = R[j];
            j++;
        }
        else if (j > n2){
            A[k] = L[i];
            i++;
        }
        else if (L[i] <= R[j]){
            A[k] = L[i];
            i++;
        }
        else{
            A[k] = R[j];
            j++;
        }
    }
}

public static void mergeSort(int[] A, int p, int r){
    if (p < r){
        int q = (p + r) / 2;
        mergeSort(A, p, q);
        mergeSort(A, q+1, r);
        merge(A, p, q, r);
    }
}

我正在尝试在测试数组上实现合并排序,但我不确定为什么我会收到 ArrayIndexOutOfBoundsException 错误。任务是更改合并排序代码,使其在搜索时不使用任何哨兵。

    Before: 5 4 3 5 7 5 1 5 96 
    Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
    at Lab1_2.merge(Lab1_2.java:28)
    at Lab1_2.mergeSort(Lab1_2.java:61)
    at Lab1_2.mergeSort(Lab1_2.java:59)
    at Lab1_2.mergeSort(Lab1_2.java:59)
    at Lab1_2.mergeSort(Lab1_2.java:59)
    at Lab1_2.main(Lab1_2.java:8)

这是我收到的错误消息。

【问题讨论】:

  • 你在哪一行得到错误?请显示完整的堆栈跟踪
  • 我很好奇为什么你从 1 开始你的数组循环并一直到它相等。这会导致错误,因为循环超出了数组中的元素,然后您的程序尝试访问它
  • 我这样做了,因为我遵循的是我书中的伪代码。我会尝试改变它,看看会发生什么。

标签: java sorting merge


【解决方案1】:

您收到 ArrayIndexOutOfBoundsException 运行时异常,因为您尝试访问数组边界(限制)之外的数组。 在合并方法中,您的语句如

 int[] L = new int[n1];

您声明大小为 n1 的数组,您可以获得索引从 0 到 n-1 的元素。 但是您尝试将元素存储在索引 n1 处。这是不可能的,因为我们知道数组的元素从 0 到 size-1(这里的 size 是数组的长度)这是原因之一。你在其他地方有问题。 所以我编辑了你的代码,希望下面的代码对你有用。

/* package whatever; // don't place package name! */

import java.util.*;

import java.lang.*;

import java.io.*;


class Ideone
    {
    public static void main (String[] args) throws java.lang.Exception
    {
    // your code goes here
        int[] test = {5,4,3,5,7,5,1,5,96};
    System.out.print("Before: ");
    printList(test);
    mergeSort(test, 0, test.length-1);
    System.out.print("After:  ");
    printList(test);
}

public static void printList(int[] test){
for (int i= 0; i < test.length; i++){
    System.out.print(test[i] + " ");
}
System.out.println();
}

public static void merge(int[] A, int p, int q, int r){
int n1 = q - p + 1;
int n2 = r - q;

int[] L = new int[n1];
int[] R = new int[n2];

for(int i = 0; i < n1; i++){
    L[i] = A[p+i];
}
for (int j = 0; j < n2; j++){
    R[j] = A[q+j+1];
}
//int i = 0;
//int j = 0;

   /* for (int k=p; i <= r; i++){
    if (i > n1){
        A[k] = R[j];
        j++;
    }
    else if (j > n2){
        A[k] = L[i];
        i++;
    }
    else if (L[i] <= R[j]){
        A[k] = L[i];
        i++;
    }
    else{
        A[k] = R[j];
        j++;
    }
    }*/

       int i = 0, j = 0;


    int k = p;
    while (i < n1 && j < n2)
    {
        if (L[i] <= R[j])
        {
            A[k] = L[i];
            i++;
        }
        else
        {
            A[k] = R[j];
            j++;
        }
        k++;
    }


    while (i < n1)
    {
        A[k] = L[i];
        i++;
        k++;
    }


    while (j < n2)
    {
        A[k] = R[j];
        j++;
        k++;
    }

}

public static void mergeSort(int[] A, int p, int r){
if (p < r){
    int q = (p + r) / 2;
    mergeSort(A, p, q);
    mergeSort(A, q+1, r);
    merge(A, p, q, r);
}
}

}

【讨论】:

    【解决方案2】:

    小心他们的数组索引,改为 main

       mergeSort(test,0, test.length-1); // change array init index 0
    

    【讨论】:

    • 我试过这样做,但我仍然得到同样的错误。
    【解决方案3】:

    更好的可读性解决方案可能是

    public class MergeSort {
    
        private int[] array;
        private int[] tempMergArr;
        private int length;
    
        public static void main(String a[]){
    
            int[] inputArr = {5,4,3,5,7,5,1,5,96};
            System.out.print("Before: ");
            printList(inputArr);
            MergeSort mms = new MergeSort();
            mms.sort(inputArr);
            System.out.print("After: ");
            printList(inputArr);
        }
    
        public static void printList(int[] test){
            for (int i= 0; i < test.length; i++){
                System.out.print(test[i] + " ");
            }
            System.out.println();
        }
        public void sort(int inputArr[]) {
            this.array = inputArr;
            this.length = inputArr.length;
            this.tempMergArr = new int[length];
            mergeSort(0, length - 1);
        }
    
        private void mergeSort(int lowerIndex, int higherIndex) {
    
            if (lowerIndex < higherIndex) {
                int middle = lowerIndex + (higherIndex - lowerIndex) / 2;
                // Below step sorts the left side of the array
                mergeSort(lowerIndex, middle);
                // Below step sorts the right side of the array
                mergeSort(middle + 1, higherIndex);
                // Now merge both sides
                merge(lowerIndex, middle, higherIndex);
            }
        }
    
        private void merge(int lowerIndex, int middle, int higherIndex) {
    
            for (int i = lowerIndex; i <= higherIndex; i++) {
                tempMergArr[i] = array[i];
            }
            int i = lowerIndex;
            int j = middle + 1;
            int k = lowerIndex;
            while (i <= middle && j <= higherIndex) {
                if (tempMergArr[i] <= tempMergArr[j]) {
                    array[k] = tempMergArr[i];
                    i++;
                } else {
                    array[k] = tempMergArr[j];
                    j++;
                }
                k++;
            }
            while (i <= middle) {
                array[k] = tempMergArr[i];
                k++;
                i++;
            }
    
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-10-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多