MergeSort的Java实现;找不到错误
好吧,这是一个令人绝望的问题。我正在尝试实现自底向上的MS来排序和整数数组。但看在上帝的份上,我好像找不到虫子MergeSort的Java实现;找不到错误,java,algorithm,sorting,debugging,mergesort,Java,Algorithm,Sorting,Debugging,Mergesort,好吧,这是一个令人绝望的问题。我正在尝试实现自底向上的MS来排序和整数数组。但看在上帝的份上,我好像找不到虫子 import java.util.Scanner; public class A2 { public static boolean less(Integer v, Integer w) { return v.compareTo(w) < 0; } public static void sort(int[] a) { i
import java.util.Scanner;
public class A2 {
public static boolean less(Integer v, Integer w) {
return v.compareTo(w) < 0;
}
public static void sort(int[] a) {
int N = a.length;
int[] aux = new int[N];
for (int sz = 1; sz < N; sz = sz + sz)
for (int lo = 0; lo < N - sz; lo += sz + sz)
merge(a, aux, lo, lo + sz - 1, Math.min(lo + sz + sz - 1, N - 1));
}
public static void merge(int[] a, int aux[], int lo, int mid, int hi) {
int i = lo;
int j = mid + 1;
for (int k = lo; k <= hi; k++)
aux[k] = a[k];
for (int k = lo; k <= hi; k++)
if (i > mid)
a[k] = aux[j++];
else if (j > hi)
a[k] = aux[i++];
else if (less(aux[j], aux[i]))
a[k] = a[j++];
else
a[k] = a[i++];
}
public static void main(String[] args) {
int next = 0;
Scanner scanner = new Scanner(System.in);
int size = Integer.parseInt(scanner.nextLine());
int[] v = new int[size];
String s = scanner.nextLine();
scanner.close();
String[] sa = s.split("[\\s]+");
while (next < size) {
v[next] = Integer.parseInt(sa[next]);
next ++;
}
for (Integer i : v)
System.out.print(i + " ");
System.out.println();
System.out.println("----------------------------------");
sort(v);
for (int i = 0; i < size; i++)
System.out.print(v[i] + " ");
System.out.println();
}
}
最后一个看起来很好
请帮帮我,我已经走来走去,似乎找不到bug。您可以尝试使用以下代码:
import java.util.Arrays;
public class MergeSort
{
public static void merge(double[] a,
int iLeft, int iMiddle, int iRight,
double[] tmp)
{
int i, j, k;
i = iLeft;
j = iMiddle;
k = iLeft;
while ( i < iMiddle || j < iRight )
{
if ( i < iMiddle && j < iRight )
{ // Both array have elements
if ( a[i] < a[j] )
tmp[k++] = a[i++];
else
tmp[k++] = a[j++];
}
else if ( i == iMiddle )
tmp[k++] = a[j++]; // a is empty
else if ( j == iRight )
tmp[k++] = a[i++]; // b is empty
}
/* =================================
Copy tmp[] back to a[]
================================= */
for ( i = iLeft; i < iRight; i++ )
a[i] = tmp[i];
}
public static void sort(double[] a, double[] tmp)
{
int width;
for ( width = 1; width < a.length; width = 2*width )
{
// Combine sections of array a of width "width"
int i;
for ( i = 0; i < a.length; i = i + 2*width )
{
int left, middle, right;
left = i;
middle = i + width;
right = i + 2*width;
merge( a, left, middle, right, tmp );
}
System.out.println("After 1 iter: " + Arrays.toString(a) );
}
}
}
导入java.util.array;
公共类合并排序
{
公共静态无效合并(双[]a,
int iLeft,int IMIDLE,int iRight,
双[]tmp)
{
int i,j,k;
i=iLeft;
j=imidle;
k=iLeft;
而(i
您可以尝试使用以下代码:
import java.util.Arrays;
public class MergeSort
{
public static void merge(double[] a,
int iLeft, int iMiddle, int iRight,
double[] tmp)
{
int i, j, k;
i = iLeft;
j = iMiddle;
k = iLeft;
while ( i < iMiddle || j < iRight )
{
if ( i < iMiddle && j < iRight )
{ // Both array have elements
if ( a[i] < a[j] )
tmp[k++] = a[i++];
else
tmp[k++] = a[j++];
}
else if ( i == iMiddle )
tmp[k++] = a[j++]; // a is empty
else if ( j == iRight )
tmp[k++] = a[i++]; // b is empty
}
/* =================================
Copy tmp[] back to a[]
================================= */
for ( i = iLeft; i < iRight; i++ )
a[i] = tmp[i];
}
public static void sort(double[] a, double[] tmp)
{
int width;
for ( width = 1; width < a.length; width = 2*width )
{
// Combine sections of array a of width "width"
int i;
for ( i = 0; i < a.length; i = i + 2*width )
{
int left, middle, right;
left = i;
middle = i + width;
right = i + 2*width;
merge( a, left, middle, right, tmp );
}
System.out.println("After 1 iter: " + Arrays.toString(a) );
}
}
}
导入java.util.array;
公共类合并排序
{
公共静态无效合并(双[]a,
int iLeft,int IMIDLE,int iRight,
双[]tmp)
{
int i,j,k;
i=iLeft;
j=imidle;
k=iLeft;
而(i
通过此更改,它可以在我的系统上运行
else if(less(aux[j], aux[i]))
a[k] = aux[j++]; // fix (aux)
else
a[k] = aux[i++]; // fix (aux)
如果合并排序通过更改每个过程的合并方向来避免复制步骤,则如果在合并过程的末尾有一个剩余的运行,则需要复制它。这个答案的第三部分有一个例子
当我使用带有随机值的较大数组(如800万整数)进行测试时,使用less(…)会间歇性地使系统的运行时间翻倍。将if(less(aux[j],aux[i])更改为if(aux[j]
一种更有效的合并排序的示例代码,它避免了进行复制,除非有奇数次的传递。这可以通过首先计算通过次数来避免,如果通过次数为奇数,则进行交换。通过在初始过程中对32或64个元素的组使用插入排序,可以将其扩展到更大的子组
public static void sort(int[] a) {
int n = a.length;
if(n < 2)
return;
int[] dst = new int[n];
int[] src = a;
int[] tmp;
for(int sz = 1; sz < n; sz = sz+sz){
int lo;
int md;
int hi = 0;
while(hi < n){
lo = hi;
md = lo+sz;
if(md >= n){ // if single run remaining, copy it
System.arraycopy(src, lo, dst, lo, n-lo);
break;
}
hi = md+sz;
if(hi > n)
hi = n;
merge(src, dst, lo, md, hi);
}
tmp = src; // swap references
src = dst; // to change direction of merge
dst = tmp;
}
if(src != a) // copy back to a if needed
System.arraycopy(src, 0, a, 0, n);
}
public static void merge(int[] src, int[] dst, int lo, int md, int hi) {
int i = lo;
int j = md;
int k = lo;
while(true){
if(src[j]< src[i]){
dst[k++] = src[j++];
if(j < hi)
continue;
System.arraycopy(src, i, dst, k, md-i);
return;
} else {
dst[k++] = src[i++];
if(i < md)
continue;
System.arraycopy(src, j, dst, k, hi-j);
return;
}
}
}
公共静态无效排序(int[]a){
int n=a.长度;
if(n<2)
返回;
int[]dst=新的int[n];
int[]src=a;
int[]tmp;
对于(int-sz=1;sz=n){//如果剩余单次运行,则复制它
系统阵列副本(src、lo、dst、lo、n-lo);
打破
}
hi=md+sz;
如果(hi>n)
hi=n;
合并(src、dst、lo、md、hi);
}
tmp=src;//交换引用
src=dst;//更改合并方向
dst=tmp;
}
if(src!=a)//如果需要,复制回a
数组副本(src,0,a,0,n);
}
公共静态无效合并(int[]src、int[]dst、int-lo、int-md、int-hi){
int i=lo;
int j=md;
int k=lo;
while(true){
if(src[j]
通过此更改,它可以在我的系统上运行
else if(less(aux[j], aux[i]))
a[k] = aux[j++]; // fix (aux)
else
a[k] = aux[i++]; // fix (aux)
如果合并排序是通过更改每次传递的合并方向来避免复制步骤,则