【问题标题】:Simple Merge Sort in JavaJava中的简单合并排序
【发布时间】:2015-04-05 23:44:59
【问题描述】:

我正在尝试在 Java 中创建一个简单的合并排序程序。我觉得它应该可以工作,但是当我运行它时出现堆栈溢出错误:

Stack overflow at MergeSort.mergeSort(MergeSort.java:24)

我看到这里的其他几个人对此类代码有类似的问题,但我正在努力修复我的问题。任何帮助,将不胜感激。

主要代码:

import static java.lang.System.*;
import java.util.Arrays;        

public class MergeSort {

    private static int passCount;

    public static void mergeSort(Comparable[] list)
    {
        passCount = 0;
        mergeSort(list, 0, list.length);
    }

    private static void mergeSort(Comparable[] list, int front, int back)  //O( Log N )
    {
        int mid = (front + back) / 2;
        if (mid == front)
            return;
        mergeSort(list, front, mid);
        mergeSort(list, front, back);
        merge(list, front, back);
    }

    private static void merge(Comparable[] list, int front, int back)  //O(N)
    {
        Comparable[] temp = new Comparable[back - front];

        int i = front;
        int j = (front + back) / 2;
        int k = 0;
        int mid = j;

        while (i < mid && j < back)
        {
            if (list[i].compareTo(list[j]) < 0)
            {
                temp[k] = list[i];
                k++; i++;
            }
            else
            {
                temp[k] = list[j];
                k++; i++;
            }

            while(i < mid)
            {
                temp[k++] = list[i++];
            }

            while (j < back)
            {
                temp[k++] = list[j++];
            }

            for (i = 0; i < back - front; ++i)
            {
                list[front + i] = temp[i];
            }

            out.println("pass " + passCount++ + " " + Arrays.toString(list) + "\n");
        }
    }
}

我的跑步者:

public class MergeSortRunner
{
    public static void main(String args[])
    {
        MergeSort.mergeSort(new Comparable[]{ 9, 5, 3, 2 });
        System.out.println("\n");

        MergeSort.mergeSort(new Comparable[]{ 19, 52, 3, 2, 7, 21 });
        System.out.println("\n");

        MergeSort.mergeSort(new Comparable[]{ 68, 66, 11, 2, 42, 31});
        System.out.println("\n");
    }
}

【问题讨论】:

    标签: java stack-overflow mergesort


    【解决方案1】:

    你需要改变:

    mergeSort(list, front, back);
    

    收件人:

    mergeSort(list, mid, back);
    

    这将导致对mergeSort 的无限调用,因为您不会在调用之间更改任何输入参数。

    您可能还想改变:

    if(mid==front) return;
    

    到:

    if(back - front <= 1) return;
    

    此外,您对该算法的实现选择可能会导致排序不稳定,因为您正在修改列表。更好的选择是让 mergeSort 返回一个您正在排序的列表,然后实现 merge 以将两个列表作为参数,然后生成一个合并的列表。

    【讨论】:

    • 感谢您的建议。这样做可以消除堆栈溢出错误。它现在正在检查代码,但仍未正确排序。输入“9,5,3,2”在第一遍中将其排序为“5,5,3,2”,在第二遍中将其排序为“5,5,2,2”和“2,5,2,2” “在第三个,这显然意味着我没有正确设置它。再次感谢您的帮助,一旦我弄清楚了,我会再次发布。
    【解决方案2】:

    我知道这真的很晚了,但我有你要找的正确答案!

    import static java.lang.System.*;
    import java.util.Arrays;        
    
    public class MergeSort{
    
    private static int passCount;
    
    public static void mergeSort(int[] list)
    {
        passCount=0;
        mergeSort(list, 0, list.length);
    }
    
    private static void mergeSort(int[] list, int front, int back)  //O( Log N )
    {
        int mid = (front+back)/2;
        if(mid==front) return;
        mergeSort(list, front, mid);
        mergeSort(list, mid, back);
        merge(list, front, back);
    
    }
    
    private static void merge(int[] list, int front, int back)  //O(N)
    {
       int dif = back-front;
       int[] temp = new int[dif];
       int beg = front, mid = (front+back)/2;
       int saveMid = mid;
       int spot = 0;
    
       while(beg < saveMid && mid < back) {
          if(list[beg] < list[mid]) {
             temp[spot++] = list[beg++];
          } else {
             temp[spot++] = list[mid++];
          }
       }
       while(beg < saveMid)
          temp[spot++] = list[beg++];
       while(mid < back)
          temp[spot++] = list[mid++];
       for(int i = 0; i < back-front; i++) {
          list[front+i] = temp[i];
       }
        System.out.println("pass " + passCount++ + " " + Arrays.toString(list) + "\n");
      }
     }
    

    这是跑步者:

        public class MergeSortRunner {
        public static void main(String[] args) {
        MergeSort.mergeSort(new int[]{9,5,3,2});
        System.out.println();
    
        MergeSort.mergeSort(new int[]{19,52,3,2,7,21});
        System.out.println();
    
        MergeSort.mergeSort(new int[]{68,66,11,2,42,31});
        System.out.println();
       }
    }
    

    事实证明,使用 while 循环遍历列表可以帮助您返回正确的值!

    【讨论】:

    • 我不知道是什么迫使你在这么多年后回答我这个糟糕的问题,也不知道是什么让你知道你的努力会得到很少的关注,但我不得不感觉到它来自传播知识和教育那些寻求答案的人的真诚愿望,无论人数多少。你是一个好人,我非常感谢你在这么多年后抽出时间来回答我的问题!继续做你的事,再次感谢你的帮助!
    • 我完全忘了我回答了这个问题,我在高中上 AP 计算机科学课,我们做了类似的事情,我只是想我会为你修改它,这样你可以获得更好的理解!感谢您的投票并将其标记为正确!
    【解决方案3】:

    尝试改变

    if(mid==front) return;
    

    if(back-front<=1) return;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-03-31
      • 2012-11-23
      • 2015-07-30
      • 1970-01-01
      • 2011-03-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多