使用插入排序和归并排序的混合排序
Hybrid sorting using insertion sort and merge sort
我希望实现一种混合算法,一旦输入数组大小变得太大,它就会从插入排序切换到归并排序。
这是我的主要功能(我目前将输入数组大小固定为 30,因为我想测试我的合并排序功能):
public static void main(String[] args) {
int[] a = genrandarray(30);
long bgn, end;
bgn = System.currentTimeMillis();
imsort(a, 0, a.length, 30);
end = System.currentTimeMillis();
for(int i = 1; i < a.length; i++){
if(a[i-1] > a[i]){
System.out.println("failed");
break;
}
}
System.out.println("milliseconds " + (end-bgn));
}
当数组大小<20时调用插入排序,否则调用归并排序:
public static void imsort(int [] slot, int b, int e, int size) {
//if smaller than 20, use insertion sort
if (e-b<=20) {
insertionSort(slot, e); //e is the length of slot[]
System.out.println("imsort entered!");
}
else {
mergesort(b, e, slot);
System.out.println("mergesort entered!");
}
}
目前我的合并排序函数出现索引 30 越界错误。
public static int merge(int n, int m, int[] slot) {
int mid = (n+m)/2;
int a = n, b = mid+1, i, tmp, cmp=0, comp=0;
//sanity check
if (m-n <= 0) return -1000;
while (a <= mid && b <= m) {
cmp = compare(slot[a], slot[b]);
comp++;
if (cmp > 0) { //slot[a] > slot[b]
tmp = slot[b++];
for (i = ++mid; i > a; i--)
slot[i] = slot[i-1];
slot[a++] = tmp;
}
else if (cmp < 0) //slot[a] < slot[b]
a++;
else {
//slot[a] == slot[b]
if (a == mid && b == m) break;
tmp = slot[b++];
a++;
for (i = ++mid; i > a; i--)
slot[i] = slot[i-1]; slot[a++] = tmp;
}
} // end of while loop;
return comp;
} // end of merge
public static int mergesort(int s, int e, int[] slot) {
//int comp =0;
int mid = (s+e)/2;
int right=0, left=0;
if(e-s>0) {
//comp++;
left = mergesort(s,mid, slot);
//comp++;
right = mergesort(mid+1,e, slot);
}
return right + left + merge(s,e,slot);
}
我不确定我的合并/合并排序函数中的错误。我可以得到一些进一步的建议吗?
a.length returns 你 30 我相信这是来自 genrandarray 方法的随机数组的长度。你的数组索引为 0 到 29。尝试像这样更改主要方法,它会成功
public static void main(String[] args) {
int[] a = genrandarray(30);
long bgn, end;
bgn = System.currentTimeMillis();
imsort(a, 0, a.length-1, 30);
end = System.currentTimeMillis();
for(int i = 1; i < a.length; i++){
if(a[i-1] > a[i]){
System.out.println("failed");
break;
}
}
System.out.println("milliseconds " + (end-bgn));
}
首先,让我祝贺一个非常好的 post 新人。您没有post发生错误的代码行并且代码不完整,所以我填写了一些空白并执行了它:
import java.util.Arrays;
import java.util.Random;
public class Test {
public static int[] genrandarray(int n)
{
int[] a = new int[n];
Random r = new Random();
for(int i=0;i<n;i++) a[i] = r.nextInt();
return a;
}
public static void main(String[] args) {
int[] a = genrandarray(30);
long bgn, end;
bgn = System.currentTimeMillis();
imsort(a, 0, a.length, 30);
end = System.currentTimeMillis();
for(int i = 1; i < a.length; i++){
if(a[i-1] > a[i]){
System.out.println("failed");
break;
}
}
System.out.println("milliseconds " + (end-bgn));
}
public static void imsort(int [] slot, int b, int e, int size) {
//if smaller than 20, use insertion sort
if (e-b<=20) {
Arrays.sort(slot, 0, e);
System.out.println("imsort entered!");
}
else {
mergesort(b, e, slot);
System.out.println("mergesort entered!");
}
}
public static int merge(int n, int m, int[] slot) {
int mid = (n+m)/2;
int a = n, b = mid+1, i, tmp, cmp=0, comp=0;
//sanity check
if (m-n <= 0) return -1000;
while (a <= mid && b <= m) {
cmp = slot[a] - slot[b];
comp++;
if (cmp > 0) { //slot[a] > slot[b]
tmp = slot[b++];
for (i = ++mid; i > a; i--)
slot[i] = slot[i-1];
slot[a++] = tmp;
}
else if (cmp < 0) //slot[a] < slot[b]
a++;
else {
//slot[a] == slot[b]
if (a == mid && b == m) break;
tmp = slot[b++];
a++;
for (i = ++mid; i > a; i--)
slot[i] = slot[i-1]; slot[a++] = tmp;
}
} // end of while loop;
return comp;
} // end of merge
public static int mergesort(int s, int e, int[] slot) {
//int comp =0;
int mid = (s+e)/2;
int right=0, left=0;
if(e-s>0) {
//comp++;
left = mergesort(s,mid, slot);
//comp++;
right = mergesort(mid+1,e, slot);
}
return right + left + merge(s,e,slot);
}
}
该错误是由于在您的合并函数中将变量 a 设置为 n,然后在行 cmp = slot[a] - slot[b]
中设置的。因为数组从0到n-1,n会导致越界异常。
我希望实现一种混合算法,一旦输入数组大小变得太大,它就会从插入排序切换到归并排序。
这是我的主要功能(我目前将输入数组大小固定为 30,因为我想测试我的合并排序功能):
public static void main(String[] args) {
int[] a = genrandarray(30);
long bgn, end;
bgn = System.currentTimeMillis();
imsort(a, 0, a.length, 30);
end = System.currentTimeMillis();
for(int i = 1; i < a.length; i++){
if(a[i-1] > a[i]){
System.out.println("failed");
break;
}
}
System.out.println("milliseconds " + (end-bgn));
}
当数组大小<20时调用插入排序,否则调用归并排序:
public static void imsort(int [] slot, int b, int e, int size) {
//if smaller than 20, use insertion sort
if (e-b<=20) {
insertionSort(slot, e); //e is the length of slot[]
System.out.println("imsort entered!");
}
else {
mergesort(b, e, slot);
System.out.println("mergesort entered!");
}
}
目前我的合并排序函数出现索引 30 越界错误。
public static int merge(int n, int m, int[] slot) {
int mid = (n+m)/2;
int a = n, b = mid+1, i, tmp, cmp=0, comp=0;
//sanity check
if (m-n <= 0) return -1000;
while (a <= mid && b <= m) {
cmp = compare(slot[a], slot[b]);
comp++;
if (cmp > 0) { //slot[a] > slot[b]
tmp = slot[b++];
for (i = ++mid; i > a; i--)
slot[i] = slot[i-1];
slot[a++] = tmp;
}
else if (cmp < 0) //slot[a] < slot[b]
a++;
else {
//slot[a] == slot[b]
if (a == mid && b == m) break;
tmp = slot[b++];
a++;
for (i = ++mid; i > a; i--)
slot[i] = slot[i-1]; slot[a++] = tmp;
}
} // end of while loop;
return comp;
} // end of merge
public static int mergesort(int s, int e, int[] slot) {
//int comp =0;
int mid = (s+e)/2;
int right=0, left=0;
if(e-s>0) {
//comp++;
left = mergesort(s,mid, slot);
//comp++;
right = mergesort(mid+1,e, slot);
}
return right + left + merge(s,e,slot);
}
我不确定我的合并/合并排序函数中的错误。我可以得到一些进一步的建议吗?
a.length returns 你 30 我相信这是来自 genrandarray 方法的随机数组的长度。你的数组索引为 0 到 29。尝试像这样更改主要方法,它会成功
public static void main(String[] args) {
int[] a = genrandarray(30);
long bgn, end;
bgn = System.currentTimeMillis();
imsort(a, 0, a.length-1, 30);
end = System.currentTimeMillis();
for(int i = 1; i < a.length; i++){
if(a[i-1] > a[i]){
System.out.println("failed");
break;
}
}
System.out.println("milliseconds " + (end-bgn));
}
首先,让我祝贺一个非常好的 post 新人。您没有post发生错误的代码行并且代码不完整,所以我填写了一些空白并执行了它:
import java.util.Arrays;
import java.util.Random;
public class Test {
public static int[] genrandarray(int n)
{
int[] a = new int[n];
Random r = new Random();
for(int i=0;i<n;i++) a[i] = r.nextInt();
return a;
}
public static void main(String[] args) {
int[] a = genrandarray(30);
long bgn, end;
bgn = System.currentTimeMillis();
imsort(a, 0, a.length, 30);
end = System.currentTimeMillis();
for(int i = 1; i < a.length; i++){
if(a[i-1] > a[i]){
System.out.println("failed");
break;
}
}
System.out.println("milliseconds " + (end-bgn));
}
public static void imsort(int [] slot, int b, int e, int size) {
//if smaller than 20, use insertion sort
if (e-b<=20) {
Arrays.sort(slot, 0, e);
System.out.println("imsort entered!");
}
else {
mergesort(b, e, slot);
System.out.println("mergesort entered!");
}
}
public static int merge(int n, int m, int[] slot) {
int mid = (n+m)/2;
int a = n, b = mid+1, i, tmp, cmp=0, comp=0;
//sanity check
if (m-n <= 0) return -1000;
while (a <= mid && b <= m) {
cmp = slot[a] - slot[b];
comp++;
if (cmp > 0) { //slot[a] > slot[b]
tmp = slot[b++];
for (i = ++mid; i > a; i--)
slot[i] = slot[i-1];
slot[a++] = tmp;
}
else if (cmp < 0) //slot[a] < slot[b]
a++;
else {
//slot[a] == slot[b]
if (a == mid && b == m) break;
tmp = slot[b++];
a++;
for (i = ++mid; i > a; i--)
slot[i] = slot[i-1]; slot[a++] = tmp;
}
} // end of while loop;
return comp;
} // end of merge
public static int mergesort(int s, int e, int[] slot) {
//int comp =0;
int mid = (s+e)/2;
int right=0, left=0;
if(e-s>0) {
//comp++;
left = mergesort(s,mid, slot);
//comp++;
right = mergesort(mid+1,e, slot);
}
return right + left + merge(s,e,slot);
}
}
该错误是由于在您的合并函数中将变量 a 设置为 n,然后在行 cmp = slot[a] - slot[b]
中设置的。因为数组从0到n-1,n会导致越界异常。