Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/346.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 合并排序的问题_Java_Sorting - Fatal编程技术网

Java 合并排序的问题

Java 合并排序的问题,java,sorting,Java,Sorting,在java作业中,我正在努力编写递归合并排序类。到目前为止,我有3种方法,一种是“驱动程序”方法来启动递归,一种是递归的mergeSort方法和一种merge方法。根据我更改的变量,我的输出要么是一个全零数组,要么是相同顺序的原始数组。唯一的问题是原始的mergeSort方法必须包含在一个数组中,merge方法不能返回任何内容。非常感谢您对我们的任何帮助 import java.util.Arrays; public class merge2 { public static void m

在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];
        }
    }
}
导入java.util.array;
公共类合并2{
公共静态void main(字符串[]args){
int[]a={22,45,1,4,89,7,0};
合并(a);
System.out.println(Arrays.toString(a));
}
公共静态无效合并排序(int[]a){
合并排序(a,0,a.length-1);
}
公共静态void合并排序(int[]a,int beg,int end){

if(beg这里是mergeSort方法的伪代码。我发现您忽略了一个或两个元素的基本情况:

if(子列表只有一个值)
无所事事
else if(子列表有两个值)
必要时切换
else//递归,将列表分成两半
查找当前子列表的中点
调用mergeSort和processleft子列表
调用mergeSort和process right子列表
合并左、右子列表
至于合并方法,它是创建一个新数组,而不是修改现有数组。我建议使用ArrayList来实现它:

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);
      }
    }
  }
private void merge(int[]a,int first,int mid,int last)
{
ArrayList left=新建ArrayList(中间-第一个+1),right=新建ArrayList(最后一个-中间);

对于(int m=first;m好的,我修复了您的解决方案。您的主要问题是在线上用
/=
标记以解决此问题。
我还修复了你在索引方面的工作。你不必在每个级别上运行整个数组。你的复杂性也会受到影响。我认为这是关于
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];
    }
}
publicstaticvoidmain(字符串[]args){
int[]a={22,45,1,4,89,7,0};
合并(a);
System.out.println(Arrays.toString(a));
}
公共静态无效合并排序(int[]a){
合并排序(a,0,a.length-1);
}
公共静态void合并排序(int[]a,int beg,int end){

如果(对于任何愿意深入研究merge sort实现的人,请加1。谢谢,我更改了我的merge sort方法以使用您的伪代码和合并方法,当我运行此程序时,我得到了一个StackOverflower错误。我忘了提一下我们不能使用arraylist,但我可以修改它。您是否尝试在调试器中单步检查代码以查看我的位置t似乎出错了?非常感谢。工作得很好。当我开始在调试模式下运行它时,我意识到我正在遍历整个数组,但不确定它的停止值。我可以问一下,如果您达到数组的上限
(mid==end),为什么在标记为//的行处
,您将值从
a
复制到
d
,并增加mid
mid++
(现在
mid==end+1
)。但是如果下半部分的数值大于上半部分的数值,您不能停在这里,您还必须复制它。如果有
(mid==end+1)
,而不是
(mid>=end)