Java 合并排序的另一个变体
我应该提供一种更有效的合并排序变体,它在使用两种相互递归的方法时避免了数组的递归分配。然而,由于它的运行时间比通常的慢,所以它并没有变得更有效。如有任何建议,将不胜感激Java 合并排序的另一个变体,java,algorithm,sorting,recursion,mergesort,Java,Algorithm,Sorting,Recursion,Mergesort,我应该提供一种更有效的合并排序变体,它在使用两种相互递归的方法时避免了数组的递归分配。然而,由于它的运行时间比通常的慢,所以它并没有变得更有效。如有任何建议,将不胜感激 public static void main(String[] args) { int[] array = {38, 27, 43, 3, 9, 82}; System.out.println("begin with: \n" + Arrays.toString(array)); System.out.
public static void main(String[] args) {
int[] array = {38, 27, 43, 3, 9, 82};
System.out.println("begin with: \n" + Arrays.toString(array));
System.out.println("------------------");
mergesort1(array, array.length);
System.out.println("------------------");
System.out.println("end with: \n" + Arrays.toString(array));
}
public static void mergesort1(int[] a, int last) {
if (last > 1) {
int l = (last / 2);
int r = last - l;
int[] leftArray = new int[l];
int[] rightArray = new int[r];
for (int i = 0; i < l; i++) {
leftArray[i] = a[i];
}
for (int i = l; i < l + r; i++) {
rightArray[i - l] = a[i];
}
mergesort1(rightArray, r);
System.arraycopy(rightArray, 0, a, l, r);
int[] t = new int[l];
mergesort2(leftArray, l, t);
System.arraycopy(t, 0, a, 0, l);
merge(t, l, last, a);
t = null;
}
}
public static void mergesort2(int[] b, int last, int[] d) {
if (last > 1) {
int l = (last / 2);
int r = last - l;
int[] leftArray = new int[l];
int[] rightArray = new int[r];
int[] dArray = new int[r];
System.arraycopy(b, 0, leftArray, 0, l);
System.arraycopy(b, l, rightArray, 0, r);
System.arraycopy(d, l, dArray, 0, r);
mergesort1(leftArray, l);
System.arraycopy(leftArray, 0, b, 0, l);
mergesort2(rightArray, r, dArray);
System.arraycopy(rightArray, 0, b, l, r);
System.arraycopy(dArray, 0, d, l, r);
merge(b, l, last, d);
} else {
d[0] = b[0]; // Trivial case
}
}
public static void merge(int[] le, int l, int n, int[] a) {
int i = 0;
int j = l;
int k = 0;
int myTemp = 0;
while ((i < l)) {
if ((le[i] <= a[j]) || (a[j] == 0)) {
if ((k < a.length)) {
a[k] = le[i];
i++;
}
} else {
if ((k < a.length)) {
int innerTemp = 0;
if (myTemp == 0) {
a[k] = a[j];
innerTemp = 1;
}
j++;
if (j == n) {
j--;
myTemp = 1;
if (innerTemp == 0) {
a[k] = le[i];
i++;
}
}
}
}
if ((k < a.length)) {
k++;
}
}
}
publicstaticvoidmain(字符串[]args){
int[]数组={38,27,43,3,9,82};
System.out.println(“以:\n“+Arrays.toString(array))开头);
System.out.println(“------------------------”;
mergesort1(数组,数组,长度);
System.out.println(“------------------------”;
System.out.println(“结束于:\n”+Arrays.toString(array));
}
公共静态void mergesort1(int[]a,int last){
如果(上次>1){
int l=(最后一个/2);
int r=最后一个-l;
int[]leftArray=新int[l];
int[]rightArray=新的int[r];
对于(int i=0;i1){
int l=(最后一个/2);
int r=最后一个-l;
int[]leftArray=新int[l];
int[]rightArray=新的int[r];
int[]dArray=新的int[r];
数组复制(b,0,leftArray,0,l);
System.arraycopy(b,l,rightArray,0,r);
系统阵列副本(d,l,dArray,0,r);
mergesort1(leftArray,l);
数组复制(leftArray,0,b,0,l);
mergesort2(右数组,r,dArray);
数组复制(右数组,0,b,l,r);
系统阵列副本(dArray,0,d,l,r);
合并(b,l,last,d);
}否则{
d[0]=b[0];//一般情况
}
}
公共静态无效合并(int[]le、int l、int n、int[]a){
int i=0;
int j=l;
int k=0;
int myTemp=0;
而((i 如果((le[i]您正在使用大量不必要的System.arraycopy
。合并后只需使用数组复制一次,即可将合并后的数组复制到原始数组中。要将子数组传递给内部函数,只需传递子数组的开始索引和结束索引。无需将它们复制到另一个数组中,p将这些复制到函数中。您正在使用大量不必要的System.arraycopy
。合并后只需使用数组复制一次,即可将合并后的数组复制到原始数组中。要将子数组传递给内部函数,只需传递子数组的开始索引和结束索引。无需复制将它们放入另一个数组中,并将它们传递给函数。为了避免递归分配,在main()或调用相互递归函数之一的entry函数中一次性分配临时缓冲区。相互递归函数只生成索引,无需在merge()时进行复制进行实际合并。此部分示例使用半闭合间隔,第一个(低)和结束作为参数
void mergesort(int[] a, int size){ // entry function
if(size < 2)
return;
int[] b = new int[size]; // allocate temp buffer just once
mergesortatoa(a, b, 0, size); // sort a
delete[] b; // delete b
}
// merge sort from a to a
void mergesortatoa(int[] a, int[] b, int low, int end)
{
if((end - low) == 1) // if just 1 element
return; // return
int mid = (low + end)/2 // or low + (end - low)/2
mergesortatob(a, b, low, mid);
mergesortatob(a, b, mid, end);
merge(b, a, low, mid, end);
}
// merge sort from a to b
void mergesortatob(int[] a, int[] b, int low, int end)
{
if((end - low) == 1){ // if just 1 element
b[low] = a[low]; // "mergesort" a to b
return; // return
}
int mid = (low + end)/2 // or low + (end - low)/2
mergesortatoa(a, b, low, mid);
mergesortatoa(a, b, mid, end);
merge(a, b, low, mid, end);
}
// merge from x to y (no copy, just y[...] = x[...])
void merge(int[] x, int[] y, int low, int mid, int end)
{
// ...
}
void mergesort(int[]a,int size){//entry函数
如果(尺寸<2)
返回;
int[]b=new int[size];//只分配一次临时缓冲区
mergesortatoa(a,b,0,size);//排序a
删除[]b;//删除b
}
//将排序从a合并到a
void mergesortatoa(int[]a,int[]b,int-low,int-end)
{
if((end-low)==1)//如果只有1个元素
return;//return
int mid=(低端+低端)/2//或低端+(低端-低端)/2
合并SORTATOB(a、b、低、中);
合并SORTATOB(a、b、中、端);
合并(b、a、低、中、端);
}
//将排序从a合并到b
void mergesortatob(int[]a,int[]b,int-low,int-end)
{
if((end-low)==1){//如果只有1个元素
b[低]=a[低];/“合并排序”a到b
return;//return
}
int mid=(低端+低端)/2//或低端+(低端-低端)/2
合并排序(a、b、低、中);
合并合并(a、b、中、端);
合并(a、b、低、中、端);
}
//从x合并到y(无副本,仅y[…]=x[…])
无效合并(int[]x,int[]y,int-low,int-mid,int-end)
{
// ...
}
为了避免递归分配,在main()或调用相互递归函数之一的entry函数中一次性分配临时缓冲区。相互递归函数只生成索引,无需在merge()时复制回进行实际合并。此部分示例使用半闭合间隔,第一个(低)和结束作为参数
void mergesort(int[] a, int size){ // entry function
if(size < 2)
return;
int[] b = new int[size]; // allocate temp buffer just once
mergesortatoa(a, b, 0, size); // sort a
delete[] b; // delete b
}
// merge sort from a to a
void mergesortatoa(int[] a, int[] b, int low, int end)
{
if((end - low) == 1) // if just 1 element
return; // return
int mid = (low + end)/2 // or low + (end - low)/2
mergesortatob(a, b, low, mid);
mergesortatob(a, b, mid, end);
merge(b, a, low, mid, end);
}
// merge sort from a to b
void mergesortatob(int[] a, int[] b, int low, int end)
{
if((end - low) == 1){ // if just 1 element
b[low] = a[low]; // "mergesort" a to b
return; // return
}
int mid = (low + end)/2 // or low + (end - low)/2
mergesortatoa(a, b, low, mid);
mergesortatoa(a, b, mid, end);
merge(a, b, low, mid, end);
}
// merge from x to y (no copy, just y[...] = x[...])
void merge(int[] x, int[] y, int low, int mid, int end)
{
// ...
}
void mergesort(int[]a,int size){//entry函数
如果(尺寸<2)
返回;
int[]b=new int[size];//只分配一次临时缓冲区
mergesortatoa(a,b,0,size);//排序a
删除[]b;//删除b
}
//将排序从a合并到a
void mergesortatoa(int[]a,int[]b,int-low,int-end)
{
if((end-low)==1)//如果只有1个元素
return;//return
int mid=(低端+低端)/2//或低端+(低端-低端)/2
合并SORTATOB(a、b、低、中);
合并SORTATOB(a、b、中、端);
合并(b、a、低、中、端);
}
//将排序从a合并到b
void mergesortatob(int[]a,int[]b,int-low,int-end)
{
if((end-low)==1){//如果只有1个元素
b[低]=a[低];/“合并排序”a到b
return;//return
}
int mid=(低端+低端)/2//或低端+(低端-低端)/2
合并排序(a、b、低、中);
合并合并(a、b、中、端);
合并(a、b、低、中、端);
}
//从x合并到y(无副本,仅y[…]=x[…])
38, 27, 43, 3, 9, 82
- - - - - -
====================== (in-place 0-1 and 3-4)
27, 38, 43, 3, 9, 82
- - - - - -
====================== (to copy, 0-2 and 3-5)
- - - - - -
27, 38, 43, 3, 9, 82
====================== (to original, 0-5)
3, 9, 27, 38, 43, 82
- - - - - -