我正在尝试使用Java从“Introduction to algorithm”一书中实现合并排序算法,但是当我执行代码时,我输出了半排序:
input = 2,4,5,1,2,3,6,7
output = 2,2,3,4,5,1,2,7
public class Main {
public static void main(String[] args) {
int A[] = {
2, 4, 5, 1, 2, 3, 6, 7
};
int B[] = new Main().mergeSort(A, 0, A.length);
for (int i = 0; i < B.length; i++) {
System.out.println(B[i]);
}
}
void merge(int A[], int p, int q, int r) {
int n1 = q - p + 1;
int n2 = r - q;
System.out.println("-n1: " + n1 + " n2: " + n2);
int L[] = new int[n1];
int R[] = new int[n2];
for (int i = 0; i < n1; i++) {
L[i] = A[p + i];
System.out.println("L--|" + L[i]);
}
for (int j = 0; j < n2; j++) {
R[j] = A[q + j];
System.out.println("R--|" + R[j]);
}
int i = 0;
int j = 0;
for (int k = p; k < r; k++) {
if (L[i] <= R[j]) {
A[k] = L[i];
System.out.println("A--|" + A[k] + " i: " + i);
i = i + 1;
} else {
A[k] = R[j];
System.out.println("A--|" + A[k] + " j: " + j);
j = j + 1;
}
if (i == L.length || j == R.length) break;
}
}
int[] mergeSort(int A[], int p, int r) {
if (p < r) {
int q = (int) Math.floor((p + r) / 2);
mergeSort(A, p, q);
mergeSort(A, q + 1, r);
System.out.println("q: " + q + " p: " + p + " r:" + r);
merge(A, p, q, r);
}
return A;
}
}
如果有人可以帮我这个代码,我将不胜感激。我知道Java中有很多现成的实现,在这种形式下,我只想知道我的代码有什么问题。
答案 0 :(得分:1)
不要使用printf()进行调试。它可以帮助您查看正在发生的事情,但是放置断点并使用调试器。这将为你清理,但这里有一些你可以立即做的建议:
不要将变量命名为p,q,r等。将它们重命名为“high”,“low”,“middle”。将“n1”重命名为leftLen等。这极大地提高了其他程序员的可读性,并帮助您了解正在发生的事情。
想想你的程序在做什么。您的“mergeSort()”完全是标准的,因此问题必须在您的合并程序中。而不是运行mergeSort,自己运行合并,看看发生了什么。尝试了解您的合并程序是如何工作的,并将其与您正在做的事情进行比较。
具体来说,考虑你的L []和R []。他们可以空着吗?如果是这样,会发生什么?
重复怎么样?你能在左右阵列中存储相同的数字吗?这会影响您的代码吗?
有没有更好的方法存储数字范围?
祝你好运!
答案 1 :(得分:1)
感谢您的建议,我设法使其工作如下所示。
void merge(int A[], int low, int mid, int high) {
int leftN = mid - low + 1;
int rightN = high - mid;
System.out.println("n1: " + leftN + " n2: " + rightN + " q: " + mid + " p: " + low + " r:" + high);
int L[] = new int[leftN + 1];
int R[] = new int[rightN + 1];
L[leftN] = Integer.MAX_VALUE;
R[rightN] = Integer.MAX_VALUE;
for (int i = 0; i < leftN; i++) {
L[i] = A[low + i - 1];
System.out.println("L--|" + L[i]);
}
for (int j = 0; j < rightN; j++) {
R[j] = A[mid + j];
System.out.println("R--|" + R[j]);
}
int i = 0;
int j = 0;
for (int k = low - 1; k < high; k++) {
if (L[i] <= R[j]) {
A[k] = L[i];
System.out.println("A--|" + A[k] + " i: " + i + " R[i] " + L[i]);
i++;
} else {
A[k] = R[j];
System.out.println("A--|" + A[k] + " j: " + j + " R[j] " + R[j]);
j++;
}
}
}
int[] mergeSort(int A[], int low, int high) {
if (low < high) {
int mid = (low + high) / 2;
System.out.println("q: " + mid + " p: " + low + " r:" + high);
mergeSort(A, low, mid);
mergeSort(A, mid + 1, high);
merge(A, low, mid, high);
}
return A;
}