对于我的java作业,我正在努力编写一个递归合并排序类。截至目前,我有3个方法,一个“驱动”方法来启动递归,递归mergeSort
方法和merge
方法。根据我更改的变量,我的输出是一个全零的数组或我的原始数组以相同的顺序。唯一的原因是原始mergeSort
方法必须采用一个数组,merge
方法不能返回任何内容。任何帮助都非常感激
import java.util.Arrays;
public class merge2 {
public static void main(String[] args){
int []a={22,45,1,4,89,7,0};
mergeSort(a);
System.out.println(Arrays.toString(a));
}
public static void mergeSort(int [] a){
mergeSort(a,0,a.length-1);
}
public static void mergeSort(int []a, int beg,int end){
if(beg<end){
int mid=(beg+end)/2;
mergeSort(a,beg,mid);
mergeSort(a,mid+1,end);
merge(a,beg,mid,end);
}
}
private static void merge(int []a, int beg, int middle, int end){
int [] d=new int[a.length];
int mid=middle+1; //start of second half of array
for(int i=0;i<d.length;i++){
if(beg<=middle && mid<=end){
if(a[beg]<=a[mid]) {
d[i]=a[beg];
beg++;
} else if(a[mid]<=a[beg]){
d[i]=a[mid];
mid++;
}
}else if(beg>middle){
d[i]=a[mid];
mid++;
}else if(mid==a.length){
d[i]=a[beg];
beg++;
}
}
for(int w=0;w<d.length;w++){
a[w]=d[w];
}
}
}
答案 0 :(得分:3)
这是mergeSort方法的伪代码。我看到你忽略了一两个元素的基本情况:
if (sublist has only one value)
do nothing
else if (sublist has two values)
switch if necessary
else // recursion, divide list into two halves
Find midpoint of current sublist
Call mergeSort and process left sublist
Call mergeSort and process right sublist
merge left and right sublists
对于您的合并方法,它正在创建一个新数组,而不是修改现有数组。我建议使用ArrayLists来实现它:
private void merge(int[] a, int first, int mid, int last)
{
ArrayList<Integer> left = new ArrayList<Integer>(mid - first + 1), right = new ArrayList<Integer>(last - mid);
for(int m = first; m <= mid; ++m) //initialize left sublist
{
left.add(a[m]);
}
for(int m = mid + 1; m <= last; ++m) //initialize right sublist
{
right.add(a[m]);
}
int i = first;
while(!left.isEmpty() || !right.isEmpty()) //while either list has an element
{
if(left.isEmpty())
{
a[i++] = right.remove(0);
}
else if(right.isEmpty())
{
a[i++] = left.remove(0);
}
else if (left.get(0) < right.get(0))
{
a[i++] = left.remove(0);
}
else
{
a[i++] = right.remove(0);
}
}
}
答案 1 :(得分:1)
好的我修复了你的解决方案。您的主要问题是在标有//<= here
的行上。当mid
在结束索引上运行时,您没有将a
的值分配给d
,因此它会被0
填充。您必须将==
替换为>=
才能解决此问题
我还用索引修复了你的工作。您不必在每个级别上运行整个数组。你的复杂性也会受到这种影响。我认为它是关于O(n^2)
。仅运行在此递归级别上处理的部分数组就足以保持O(nlog(n))
复杂性。
固定算法如下
public static void main(String[] args){
int []a={22,45,1,4,89,7,0};
mergeSort(a);
System.out.println(Arrays.toString(a));
}
public static void mergeSort(int [] a){
mergeSort(a,0,a.length-1);
}
public static void mergeSort(int []a, int beg,int end){
if(beg<end){
int mid=(beg+end)/2;
mergeSort(a,beg,mid);
mergeSort(a,mid+1,end);
merge(a,beg,mid,end);
}
}
private static void merge(int []a, int beg, int middle, int end){
int [] d=new int[a.length];
int mid=middle+1; //start of second half of array
int beg1=beg;
for(int i=beg1;i<=end;i++){
if(beg<=middle && mid<=end){
if(a[beg]<=a[mid]) {
d[i]=a[beg];
beg++;
} else if(a[mid]<=a[beg]){
d[i]=a[mid];
mid++;
}
}else if(beg>middle){
d[i]=a[mid];
mid++;
}else if(mid>=end){ //<= here
d[i]=a[beg];
beg++;
}
}
for(int w=beg1;w<=end;w++){
a[w]=d[w];
}
}