Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.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_Algorithm_Sorting_Arraylist - Fatal编程技术网

Java合并排序算法错误-未排序

Java合并排序算法错误-未排序,java,algorithm,sorting,arraylist,Java,Algorithm,Sorting,Arraylist,我不明白为什么我使用ArrayList的合并排序程序的算法不起作用。。。如果男人和女孩能帮我弄明白这件事,那就太棒了!!打印所需的格式需要为每个数字打上标签,并每20个数字换一行。我的程序也仅限于标准Java包。可以找到样本输入和输出。这是我的密码: import java.io.*; import java.util.*; public class MergeSort { public static void main(String[] args) throws IOException{

我不明白为什么我使用ArrayList的合并排序程序的算法不起作用。。。如果男人和女孩能帮我弄明白这件事,那就太棒了!!打印所需的格式需要为每个数字打上标签,并每20个数字换一行。我的程序也仅限于标准Java包。可以找到样本输入和输出。这是我的密码:

import java.io.*;
import java.util.*;

public class MergeSort {
public static void main(String[] args) throws IOException{
    Scanner in  = new Scanner(System.in);
    Random r = new Random();
    int size, largestInt, holder;

    System.out.println("How many integers would you like me to create?");
    size = in.nextInt();
    ArrayList<Integer>list = new ArrayList<Integer>(size);
    System.out.println("What would the largest integer be?");
    largestInt = in.nextInt();

    for(int i = 0; i < size; i++){
        holder = r.nextInt(largestInt + 1);
        list.add(holder);
    }
    mergeSort(list);

    for (int j = 0; j < list.size(); j++) {
        if(j == 19 || j == 39 || j == 59 || j == 79 || j == 99 || j == 119 || j == 139 || j == 159 || j == 179 || j == 199){
            System.out.print(list.get(j));
            System.out.println();
        }
        else{
            System.out.print(list.get(j) + "\t");
        }
    }
}

static void mergeSort(ArrayList<Integer> list) {
    if (list.size() > 1) {
        int q = list.size()/2;
        ArrayList<Integer> leftList = new ArrayList<Integer>();
        for(int i = 0; i >0 && i <= q; i++){
            leftList.add(list.get(i));
        }
        ArrayList<Integer> rightList = new ArrayList<Integer>();
        for(int j = 0; j > q && j < list.size(); j++){
            rightList.add(list.get(j));
        }

        mergeSort(leftList);
        mergeSort(rightList);
        merge(list,leftList,rightList);
    }
}

static void merge(ArrayList<Integer> a, ArrayList<Integer> l, ArrayList<Integer> r) {
    int totElem = l.size() + r.size();
    int i,li,ri;
    i = li = ri = 0;
    while ( i < totElem) {
        if ((li < l.size()) && (ri<r.size())) {
            if (l.get(li) < r.get(ri)) {
                a.set(i, l.get(li));
                i++;
                li++;
            }
            else {
                a.set(i, r.get(ri));
                i++;
                ri++;
            }
        }
        else {
            if (li >= l.size()) {
                while (ri < r.size()) {
                    a.set(i, r.get(ri));
                    i++;
                    ri++;
                }
            }
            if (ri >= r.size()) {
                while (li < l.size()) {
                    a.set(i, l.get(li));
                    li++;
                    i++;
                }
            }
        }
    }
}
import java.io.*;
导入java.util.*;
公共类合并排序{
公共静态void main(字符串[]args)引发IOException{
扫描仪输入=新扫描仪(系统输入);
随机r=新随机();
内部尺寸,最大尺寸,支架;
System.out.println(“您希望我创建多少个整数?”);
大小=in.nextInt();
ArrayList=新的ArrayList(大小);
System.out.println(“最大的整数是多少?”);
largestInt=in.nextInt();
对于(int i=0;i1){
int q=list.size()/2;
ArrayList leftList=新建ArrayList();
对于(inti=0;i>0&&iq&&j=r.size()){
而(li

提前感谢!

您的问题还不清楚,但由于您需要实现合并排序算法,我认为这部分对您来说是不完整的。一旦您有了正确排序的列表,通过反复试验,格式打印应该相当容易

我认为您的解决方案中的问题过于复杂了。MergeSort是最简单的排序算法之一,但您的代码远不简单

想想合并排序是如何工作的——它本质上是递归的,因为它是一种分而治之的方法。它通过将大型复杂问题分解为简单的小问题来解决,基本上只是合并所有这些问题的结果——您的合并排序算法只需要包含这一点

如果我们写下来,您需要执行以下步骤:

(1) 检查列表是否只包含一个元素-那么它已经排序了

(2) 将输入拆分为大小相等的列表,并在继续之前对这些列表进行排序(递归步骤)

(3) 合并两个已排序列表,并返回单个已排序列表

我发现您对合并部分有一个复杂的方法,并对拆分部分使用基本迭代。Java List(例如,
ArrayList
的超类)提供了一个
。subList(fromIndex,toIndex)
将列表拆分为较小的列表。您应该使用此方法。对于合并部分:

基于维基百科的动画

如何合并这两个列表应该非常简单:

首先,将两个列表维护为易于删除对象的列表。因为此时我们知道列表将被排序,所以我们只对每个列表中的第一个对象(最小的元素)感兴趣

第二,我们只需要比较每个列表的第一个元素,从其各自的列表中删除两个元素中最小的元素,并将其添加到已排序的列表中。我们一直这样做,直到两个列表都为空-此时,我们已经合并了列表

在Java中,这表明我们应该为合并部分使用一个数据结构,该结构允许我们查看每个列表的第一个元素,并快速删除我们感兴趣的元素。在Java中,此数据结构是LinkedList-ArrayList,这两个数据结构在执行此任务时都非常糟糕,并且没有提供正确的方法。LinkedList的行为如下一个队列,提供了方便地检查和删除列表末尾对象(例如第一个元素)的方法

因此,您应该重新考虑您的实现策略,并根据您应该如何攻击MergeSort算法来简化代码。如果看起来不一致,这里是一个仅使用标准API(无内置排序方法)在Java中实现MergeSort的示例

希望能有帮助

import java.util.LinkedList;
import java.util.Random;
import java.util.List;

public class Main {

    public static void main(String[] args){

        Random random = new Random();
        LinkedList<Integer> unsorted = new LinkedList<Integer>();
        for(int i = 0; i<100; i++){
            unsorted.add(random.nextInt(100));
        }

        System.out.println("unsorted: " + unsorted.toString());

        List<Integer> sorted = mergeSort(unsorted);

        System.out.println("sorted: " + sorted.toString());
    }

    //Recursive function for sorting a LinkedList
    private static LinkedList<Integer> mergeSort(LinkedList<Integer> unsorted){

        //If the list only contains 1 object it is sorted
        if(unsorted.size() == 1){
            return unsorted;
        }

        //Split the list in two parts and create a new list to store our sorted list
        LinkedList<Integer> left = mergeSort(new LinkedList<Integer>(unsorted.subList(0, unsorted.size()/2)));
        LinkedList<Integer> right = mergeSort(new LinkedList<Integer>(unsorted.subList(unsorted.size()/2, unsorted.size())));
        LinkedList<Integer> sorted = new LinkedList<Integer>();

        //Actual loop for merging the two sublists. Using LinkedLists, this is efficient. (Compared to ArrayList)
        while(!left.isEmpty() || !right.isEmpty()){
            Integer leftInt = left.peekFirst();
            Integer rightInt = right.peekFirst();

            if(!(leftInt == null) && !(rightInt == null)){
                if(leftInt < rightInt){
                    sorted.add(left.pollFirst());
                }
                else{
                    sorted.add(right.pollFirst());
                }
            }
            else if(leftInt == null){
                sorted.add(right.pollFirst());
            }
            else{
                sorted.add(left.pollFirst());
            }
        }

        return sorted;
    }
}
import java.util.LinkedList;
导入java.util.Random;
导入java.util.List;
公共班机{
公共静态void main(字符串[]args){
随机=新随机();
LinkedList unsorted=新建LinkedList();

对于(int i=0;iIn以什么方式断开?向我们展示一些输出示例。@chm052它需要按从最小值到最大值的顺序打印出来,并且必须使用合并排序算法进行排序(即1,2,3,4,6,19,67,89)当前打印的是什么?向我们展示一些带有相应输入的示例输出。@chm052这里有一个指向输入和输出的链接。正如您所见,它没有正确排序:您的
for
循环初始化步骤和
mergeSort
中的测试没有执行您试图执行的操作。不过,我怀疑这是您唯一的错误。哈哈,我会的如果我的老师没有要求我们只使用ArrayList和递归,我会这么做。很抱歉,我的问题不清楚