Java 合并排序的问题
在java作业中,我正在努力编写递归合并排序类。到目前为止,我有3种方法,一种是“驱动程序”方法来启动递归,一种是递归的Java 合并排序的问题,java,sorting,Java,Sorting,在java作业中,我正在努力编写递归合并排序类。到目前为止,我有3种方法,一种是“驱动程序”方法来启动递归,一种是递归的mergeSort方法和一种merge方法。根据我更改的变量,我的输出要么是一个全零数组,要么是相同顺序的原始数组。唯一的问题是原始的mergeSort方法必须包含在一个数组中,merge方法不能返回任何内容。非常感谢您对我们的任何帮助 import java.util.Arrays; public class merge2 { public static void m
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
,并增加midmid++
(现在mid==end+1
)。但是如果下半部分的数值大于上半部分的数值,您不能停在这里,您还必须复制它。如果有(mid==end+1)
,而不是(mid>=end)
。