问题描述
我有一个关于将 Cormen 的合并排序算法修改为 3 路合并的作业。我的老师不喜欢书外的材料,所以我严格遵守 cormen 算法。现在,我已经尝试这样做了,但它如何显示这样的东西
Exception in thread "main" java.lang.NegativeArraySizeException: -1
at Algorithms.Mergemod.merge(Mergemod.java:10)
at Algorithms.Mergemod.mergeSort(Mergemod.java:60)
at Algorithms.Mergemod.mergeSort(Mergemod.java:58)
at Algorithms.Mergemod.mergeSort(Mergemod.java:59)
at Algorithms.Mergemod.mergeSort(Mergemod.java:58)
at Algorithms.Mergemod.main(Mergemod.java:83)
我已经尝试过调试器,在 mergeSort 函数中,我看到 r 的值有时为 1,有时为 3 而不是 11。这是我的困惑,为什么 r 会保留 1 或 3 而不是 11。我已经通过了最后一个索引数组作为函数中的 r。
我的代码:
package Algorithms;
import java.util.Scanner;
public class Mergemod {
static void merge(int [] A,int p,int q,int t,int r ){
int n1 = q-p+1;
int n2 = t-q;
int n3 = r-t;
int [] L = new int[n1];
int [] M = new int[n2];
int [] R = new int[n3];
//inserting values from A to L
for (int i = 0; i < L.length; i++) {
L[i] = A[p+i];
}
//inserting values from A to M
for (int j = 0; j < M.length; j++) {
M[j] = A[q+j+1];
}
//inserting values from A to R
for (int k = 0; k < R.length; k++) {
R[k] = A[t+k+1];
}
int i = 0,j = 0,k = 0,l;
//sorting and merging
for (l = p; l <=r && i<n1 && j<n2 && k<n3; L++) {
if(L[i]<=M[j] && L[i]<=R[k]){
A[l] = L[i];
i++;
}
else if(M[j]<=L[i] && M[j]<=R[k]){
A[l] = M[j];
j++;
}
else{
A[l] = R[k];
k++;
}
}
while(i<n1){
A[L++] = L[i++];
}
while(j<n2){
A[L++] = M[j++];
}
while(k<n3){
A[L++] = R[k++];
}
}
static void mergeSort(int [] A,int r){
if(p<r)
{ int q = (p+r)/3;
int t = (q+1+r)/2;
mergeSort(A,p,q);
mergeSort(A,q+1,t);
mergeSort(A,t+1,r);
merge(A,q,t,r);
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(system.in);
System.out.println("Enter the size of the array: ");
int [] arr = new int [sc.nextInt()];
System.out.println("Enter numbers : 11 5 20 3 4 8 0 15 2 13 1 6");
for (int i = 0; i < arr.length; i++) {
arr[i]= sc.nextInt();
}
System.out.println("Before merge sort");
for (var x : arr) {
System.out.print(x+" ");
}
int firstIndex = 0;
int lastIndex = arr.length-1;
System.err.println(" ");
System.out.println("After merge sort ");
mergeSort(arr,firstIndex,lastIndex);
for (var k : arr) {
System.out.print(k+" ");
}
sc.close();
}
}
我不知道我的逻辑是否正确,但如果有人会帮助我,那将意义重大。另外我在java方面不是很好,如果有任何可读性问题,很抱歉。 谢谢!
解决方法
随着您的进步,我会更新此答案。随着您的进步,更新您的问题。
int q = p + (r+1-p)/3; // split
int t = q + (r+2-p)/3;
在合并()中:
if (r-p) < 1,return
if (r-p) < 2,compare a[p] : a[r],swap if out order,return
3 way merge,if the end of L[] is reached,L = M,M = R,i = j,j = k,break to 2 way merge
if the end of M[] is reached,break to 2 way merge
if the end of R[] is reached,break to 2 way merge
2 way merge L[] and M[] using i and j
if the end of L[] is reached,i = j break to copy
if the end of M[] is reached,break to copy
copy the rest of L[]
,
我没有这样做,而是使用优先级队列来试试运气。将三个数组加载到最小堆中,然后将最小堆中的每个项目都移到我的数组 A 中。
PriorityQueue<Integer> minHeap = new PriorityQueue<>();
for (Integer x : L) {
minHeap.add(x);
}
for (Integer v : M) {
minHeap.add(v);
}
for (Integer g : R) {
minHeap.add(g);
}
for (int i = p; i <=r; i++) {
A[i]= minHeap.remove();
}
非常感谢您修改后的拆分。像魅力一样工作。 @rcgldr