【问题标题】:Using Merge Sort on ArrayList and LinkedList : Java在 ArrayList 和 LinkedList 上使用合并排序:Java
【发布时间】:2011-08-18 16:32:15
【问题描述】:

我需要使用归并排序对包含 1000 个整数的列表进行排序;据我所知,我的算法看起来应该可以工作,但是当我打印出“排序”列表时,它仍然没有排序。我真的很难过,我想知道是否有人能指出我正确的方向。这是我的代码:

package edu.neumont.csc250;

import java.util.Random;

import edu.neumont.csc250.LinkedList.Node;


public class Tester {

    ArrayList<Integer> arrayList1000;
    ArrayList<Integer> arrayList10000;
    ArrayList<Integer> arrayList100000;

    LinkedList<Integer> linkedList1000;
    LinkedList<Integer> linkedList10000;
    LinkedList<Integer> linkedList100000;

    public Tester(){}

    public void createLists(){
        arrayList1000 = new ArrayList<Integer>();
        arrayList1000 = populateRandoms(arrayList1000, 1000);
        arrayList10000 = new ArrayList<Integer>();
        arrayList10000 = populateRandoms(arrayList10000, 10000);
        arrayList100000 = new ArrayList<Integer>();
        arrayList100000 = populateRandoms(arrayList100000, 100000);

        linkedList1000 = new LinkedList<Integer>();
        linkedList1000 = populateRandoms(linkedList1000, 1000);
        linkedList10000 = new LinkedList<Integer>();
        linkedList10000 = populateRandoms(linkedList10000, 10000);
        linkedList100000 = new LinkedList<Integer>();
        linkedList100000 = populateRandoms(linkedList100000, 100000);
    }

    public ArrayList<Integer> populateRandoms(ArrayList<Integer> list, int size){
        Random r = new Random();

        for(int i = 0; i < size; i++){
            list.add(r.nextInt(1000) + 1);
            //System.out.println(list.get(i));
        }
        return list;
    }

    public LinkedList<Integer> populateRandoms(LinkedList<Integer> list, int size){
        Random r = new Random();

        for(int i = 0; i < size; i++){
            list.add(r.nextInt(1000) + 1);
            //System.out.println(list.get(i));
        }
        return list;
    }

    public void arraySearches(){
        System.out.println("STARTING SEARCH OF 1000 INTEGERS...");

        long startTime = System.nanoTime();
        long endTime;
        try {
            System.out.println(sequentialSearch(arrayList1000, 123));
            if(sequentialSearch(arrayList1000, 123) == -1){
                System.out.println("Not found in the list.");
            }
            else{
                //System.out.println(arrayList1000.get(sequentialSearch(arrayList1000, 123)));
            }
        } finally {
            endTime = System.nanoTime();
            long duration = endTime - startTime;
            System.out.println("1000 elements takes " + (duration/1000000000) + " seconds, " +
                (duration%1000000000)/1000000+ " milliseconds, " + (duration%1000000000)%1000000 +
                " nanoseconds to search a CustomArrayList with a sequential search.");
        }


        System.out.println("STARTING SEARCH OF 10000 INTEGERS...");

        long startTime2 = System.nanoTime();
        long endTime2;
        try {
            System.out.println(sequentialSearch(arrayList10000, 123));
            if(sequentialSearch(arrayList10000, 123) == -1){
                System.out.println("Not found in the list.");
            }
            else{
                //System.out.println(arrayList10000.get(sequentialSearch(arrayList10000, 123)));
            }
        } finally {
            endTime2 = System.nanoTime();
            long duration2 = endTime2 - startTime2;
            System.out.println("10000 elements takes " + (duration2/1000000000) + " seconds, " +
                (duration2%1000000000)/1000000+ " milliseconds, " + (duration2%1000000000)%1000000 +
                " nanoseconds to search a CustomArrayList with a sequential search.");
        }


        System.out.println("STARTING SEARCH OF 100000 INTEGERS...");

        long startTime3 = System.nanoTime();
        long endTime3;
        try {
            System.out.println(sequentialSearch(arrayList100000, 123));
            if(sequentialSearch(arrayList100000, 123) == -1){
                System.out.println("Not found in the list.");
            }
            else{
                //System.out.println(arrayList100000.get(sequentialSearch(arrayList100000, 123)));
            }
        } finally {
          endTime3 = System.nanoTime();
            long duration3 = endTime3 - startTime3;
            System.out.println("100000 elements takes " + (duration3/1000000000) + " seconds, " +
                (duration3%1000000000)/1000000+ " milliseconds, " + (duration3%1000000000)%1000000 +
                " nanoseconds to search a CustomArrayList with a sequential search.");
        }
    }

    public void linkedSearches(){
        System.out.println("STARTING SEARCH OF 1000 INTEGERS...");

        long startTime = System.nanoTime();
        long endTime;
        try{
            System.out.println(sequentialSearch(linkedList1000, 123));
            if(sequentialSearch(linkedList1000, 123) == -1){
                System.out.println("Not found in the list.");
            }
            else{
                //System.out.println(linkedList1000.get(sequentialSearch(linkedList1000, 123)));
            }
        } finally {
            endTime = System.nanoTime();
            long duration = endTime - startTime;
            System.out.println("1000 elements takes " + (duration/1000000000) + " seconds, " +
                (duration%1000000000)/1000000+ " milliseconds, " + (duration%1000000000)%1000000 +
                " nanoseconds to search a CustomLinkedList with a sequential search.");
        }


        System.out.println("STARTING SEARCH OF 10000 INTEGERS...");

        long startTime2 = System.nanoTime();
        long endTime2;
        try{
            System.out.println(sequentialSearch(linkedList10000, 123));
            if(sequentialSearch(linkedList10000, 123) == -1){
                System.out.println("Not found in the list.");
            }
            else{
                //System.out.println(linkedList10000.get(sequentialSearch(linkedList10000, 123)));
            }
        } finally {
            endTime2 = System.nanoTime();
            long duration2 = endTime2 - startTime2;
            System.out.println("10000 elements takes " + (duration2/1000000000) + " seconds, " +
                (duration2%1000000000)/1000000+ " milliseconds, " + (duration2%1000000000)%1000000 +
                " nanoseconds to search a CustomLinkedList with a sequential search.");
        }


        System.out.println("STARTING SEARCH OF 100000 INTEGERS...");

        long startTime3 = System.nanoTime();
        long endTime3;
        try{
            System.out.println(sequentialSearch(linkedList100000, 123));
            if(sequentialSearch(linkedList100000, 123) == -1){
                System.out.println("Not found in the list.");
            }
            else{
                //System.out.println(linkedList100000.get(sequentialSearch(linkedList100000, 123)));
            }
        } finally {
            endTime3 = System.nanoTime();
            long duration3 = endTime3 - startTime3;
            System.out.println("100000 elements takes " + (duration3/1000000000) + " seconds, " +
                (duration3%1000000000)/1000000+ " milliseconds, " + (duration3%1000000000)%1000000 +
                " nanoseconds to search a CustomLinkedList with a sequential search.");
        }
    }

    public void arraySorts(){
        arrayList1000 = mergeSort(arrayList1000);
        for(int i = 0; i<1000; i++){
            System.out.println(arrayList1000.get(i));
        }
    }

    public void linkedSorts(){
//      linkedList1000 = mergeSort(linkedList1000);
//      for(int i = 0; i<1000; i++){
//          System.out.println(arrayList1000.get(i));
//      }
    }

    public ArrayList<Integer> mergeSort(ArrayList<Integer> list){
        ArrayList<Integer> first = new ArrayList<Integer>();
        ArrayList<Integer> second = new ArrayList<Integer>();
        ArrayList<Integer> sortedList = null;

        System.out.println("MERGE SORTING...");
        if(list.size() > 1){
            for(int i = 0; i<(list.size()/2); i++){
                first.add(list.get(i));
            }
            for(int j = list.size()/2; j<list.size(); j++){
                second.add(list.get(j));
            }
            mergeSort(first);
            mergeSort(second);
        }
        sortedList = merge(first, second);


        return sortedList;
    }

    public ArrayList<Integer> merge(ArrayList<Integer> first, ArrayList<Integer> second){
        ArrayList<Integer> newList = new ArrayList<Integer>();

        int i = 0;
        int j = 0;

        while(i<first.size() && j<second.size()){
            if(first.get(i) <= second.get(j)){
                newList.add(first.get(i));
                i++;
            }
            else{
                newList.add(second.get(j));
                j++;
            }
        }
        if(i==first.size()){
            for(int k = j; k<second.size(); k++){
                newList.add(second.get(k));
            }
        }
        else{
            for(int l = i; l<first.size(); l++){
                newList.add(first.get(l));
            }
        }
//      while(i<first.size()){
//          for(int i : first){
//              
//          }
//          newList.add()
//      }
//      while(j<second.size()){
//          
//      }

        return newList;
    }

    public List<Integer> mergeSort(LinkedList<Integer> list){
        return list;
    }

    public int sequentialSearch(ArrayList<Integer> list, int key){
        for(int i = 0; i < list.size()-1; i++){
            if(list.get(i).equals(key)){
                return i;
            }
        }
        return -1;
    }

    public int sequentialSearch(LinkedList<Integer> list, int key){
        Node current = list.head;
        for(int i = 0; i < list.size()-1; i++){
            if(current.content.equals(key)){
                return i;
            }
        }
        return -1;
    }

    public static void main(String[] args){
        Tester t = new Tester();
        t.createLists();
        //t.arraySearches();
        //t.linkedSearches();
        t.arraySorts();
        //t.linkedSorts();
    }
}

【问题讨论】:

  • 首先,您可能希望将该示例归结为实际使用的部分。话说回来;您的代码实际上似乎在做正确的事情。此时,您可能想要添加调试输出,例如,在哪个点调用哪个方法与哪些参数、哪些元素正在连接、返回值是什么。
  • 解决方案是结合@proactif 和@Milan 的答案

标签: java algorithm merge mergesort


【解决方案1】:

我认为你应该替换

mergeSort(first);
mergeSort(second);

通过

first = mergeSort(first);
second = mergeSort(second);

【讨论】:

  • 我刚试过这个,当我尝试打印出(新)排序列表的每个元素时,它会导致抛出非法参数异常。
  • @ChrisV,那是因为 mergeSort 正在生成一个空列表,并且您假设有 1000 个元素。我对答案中的第二个错误进行了修复。
【解决方案2】:

你的 mergeSort 函数除了返回列表之外什么都不做。

public List mergeSort(LinkedList list) {
    return list;
}

你希望它如何排序?

【讨论】:

  • 你看错了。有两种方法,一种用于链表,一种用于数组列表。到目前为止,我只完成了 arrayList 一个。
  • 我也会检查该代码,但根据您的问题,您说您正在尝试对“列表”进行排序
【解决方案3】:

mergeSort(ArrayList&lt;Integer&gt; list) 中,当列表只包含1 个元素时,忽略它并尝试合并为空的firstsecond 数组列表。

如果您检查返回的排序数组列表的大小,您应该注意到它可能缺少一些元素。

【讨论】:

    【解决方案4】:

    我用调试器逐步检查了你的代码,发现了一个错误。

    first = mergeSort(first);
    second = mergeSort(second);
    

    在那之后你有一个问题,你需要正确处理一个元素。

    public ArrayList<Integer> mergeSort(ArrayList<Integer> list) {
        System.out.println("MERGE SORTING...");
        if (list.size() < 2)
            return new ArrayList<Integer>(list);
    
        ArrayList<Integer> first = new ArrayList<Integer>(list.subList(0, list.size() / 2));
        ArrayList<Integer> second = new ArrayList<Integer>(list.subList(list.size()/2, list.size()));
    
        return merge(mergeSort(first), mergeSort(second));
    }
    

    【讨论】:

    • 我假设之前的代码没有 first= 和 second= ??
    • @ChrisV,也许你应该问问最初编写代码的人。 ;)
    • 有道理,但仅供参考,我正在使用自定义集合类(自定义数组列表和自定义链接列表),所以我没有任何构造函数来接受你提到的参数。
    • 我也有点困惑,因为你似乎有无法访问的代码......一旦你遇到 list.size() 为 1 并返回 newArrayList 不会那样在到达'return merge(mergeSort(first,mergeSortsecond)) 部分之前切断方法?编辑:没关系,我知道它现在是如何工作的;我只是被你的 if 语句括起来没有括号
    • 您可以按照自己的方式复制它们。当您有一个元素时,它将在第二个列表中。 ;)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-19
    • 2018-10-16
    相关资源
    最近更新 更多