Java 三向合并排序问题排序不正确
我一直在研究这个基于我的普通合并排序代码的三向合并排序算法;但是,它没有正确排序,因此我相信我的代码中可能有一个小错误。需要帮忙吗?我已经研究了3个小时的代码,试图找到问题,但事实证明这很困难Java 三向合并排序问题排序不正确,java,mergesort,Java,Mergesort,我一直在研究这个基于我的普通合并排序代码的三向合并排序算法;但是,它没有正确排序,因此我相信我的代码中可能有一个小错误。需要帮忙吗?我已经研究了3个小时的代码,试图找到问题,但事实证明这很困难 public class TriMergeSort { void merge(int arr[], int low, int mid1, int mid2, int high) { int sizeA = mid1 - low + 1; int sizeB =
public class TriMergeSort {
void merge(int arr[], int low, int mid1, int mid2, int high) {
int sizeA = mid1 - low + 1;
int sizeB = mid2 - mid1;
int sizeC = high - mid2;
int A[] = new int[sizeA];
int B[] = new int[sizeB];
int C[] = new int[sizeC];
for (int i = 0; i < sizeA; i++)
A[i] = arr[low + i];
for (int j = 0; j < sizeB; j++)
B[j] = arr[mid1 + j + 1];
for (int x = 0; x < sizeC; x++)
C[x] = arr[mid2 + x + 1];
int i = 0, j = 0, x = 0;
int k = low;
while (i < sizeA && j < sizeB && x < sizeC) {
if (A[i] < B[j] && A[i] < C[x]) {
arr[k] = A[i];
i++;
} else
if (A[i] >= B[j] && B[j] < C[x]) {
arr[k] = B[j];
j++;
} else
if (A[i] > C[x] && B[j] >= C[x]) {
arr[k] = C[x];
x++;
}
k++;
}
while (i < sizeA) {
arr[k] = A[i];
i++;
k++;
}
while (j < sizeB) {
arr[k] = B[j];
j++;
k++;
}
while (x < sizeC) {
arr[k] = C[x];
x++;
k++;
}
}
void sort(int arr[], int low, int high) {
if (low < high) {
int mid1 = low + ((high - low) / 3);
int mid2 = low + 2 * ((high - low) / 3) + 1;
sort(arr, low, mid1);
sort(arr, mid1 + 1, mid2);
sort(arr, mid2 + 1, high);
merge(arr, low, mid1, mid2, high);
}
}
static void print(int arr[]) {
int n = arr.length;
for (int i = 0; i < n; ++i)
System.out.print(arr[i] + " ");
System.out.println();
}
public static void main(String args[]) {
int arr[] = { 15, 2, 6, 7, 55, 0, 28, 41, 12 };
TriMergeSort test = new TriMergeSort();
test.sort(arr, 0, arr.length - 1);
print(arr);
}
}
公共类TriMergeSort{
无效合并(int arr[],int low,int mid1,int mid2,int high){
int sizeA=mid1-低+1;
int sizeB=mid2-mid1;
int sizeC=高-中2;
int A[]=新的int[sizeA];
int B[]=新int[sizeB];
int C[]=新的int[sizeC];
对于(int i=0;i=B[j]&B[j]C[x]&&B[j]>=C[x]){
arr[k]=C[x];
x++;
}
k++;
}
而(i
问题中的代码运行良好。您没有发布有问题的3向合并代码
请注意,不应将high
作为索引传递给要排序的切片中的最后一项,而应将第一个元素的索引传递给切片之外的元素。这使得代码更简单,不会产生混淆和容易出错的调整
以下是修改后的版本:
公共类合并排序{
无效合并(int arr[],int low,int mid,int high){
int sizeA=中-低;
int sizeB=高-中;
int A[]=新的int[sizeA];
int B[]=新int[sizeB];
对于(int i=0;i
要将其转换为3路合并版本,sort3
必须遵循以下步骤:
- 将范围分成3个部分,而不是2个。第一个部分从
到low
排除,第二个从mid1=low+(high-low)/3
到mid1
mid2=low+(high-low)*2/3排除,第三个从
到mid2
排除high
- 对3个子切片中的每一个子切片进行递归排序
- 呼叫
merge3(arr、低、中1、中2、高)
- 复制3个子切片
- 为运行3个切片的3个索引值编写一个循环,直到其中一个已耗尽
- 为剩余的2个切片(A和B)或(B和C)或(A和C)写入3个循环
- 写3个循环以从剩余的片A、B或C复制剩余的元素
TriMergeSort
类中的merge
函数缺少3个循环,当3个初始切片中的一个用完时,这些循环将合并2个切片。这解释了数组未正确排序的原因。在3路合并循环之后,您应该有:
while (i < sizeA && j < sizeB) {
...
}
while (i < sizeA && x < sizeC) {
...
}
while (j < sizeB && x < sizeC) {
...
}
甚至更进一步:
while (low < high) {
arr[low++] = (i < sizeA && (j >= sizeB || A[i] <= B[j])) ?
((k >= sizeC || A[i] <= C[k]) ? A[i++] : C[k++]) :
(j < sizeB && (k >= sizeC || B[j] <= C[k])) ? B[j++] : C[k++];
}
while(低<高){
arr[low++]=(i=sizeB||A[i]=sizeC|A[i]=sizeC|B[j]使用调试器是一项重要技能,这是一个学习调试器的好机会。您没有发布不起作用的3向合并排序代码。编辑此帖子以显示我的3向合并排序…我的好友,请遵循java命名约定。数组名称也应以小写开头。非常感谢您提供的提示!我将帖子编辑为显示我的3路合并排序算法,因为我无意中发布了常规合并排序。
while (low < high) {
arr[low++] = (i < sizeA && (j >= sizeB || A[i] <= B[j])) ?
((k >= sizeC || A[i] <= C[k]) ? A[i++] : C[k++]) :
(j < sizeB && (k >= sizeC || B[j] <= C[k])) ? B[j++] : C[k++];
}