【问题标题】:Can't figure out what is wrong with my merge sort code无法弄清楚我的合并排序代码有什么问题
【发布时间】:2017-05-30 18:32:33
【问题描述】:

我重复了很多次,但我不确定我做错了什么。 他的逻辑似乎没问题,但它只打印出第一个数字。我省略了主要方法:

public class MergeSort {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        int[] bob = {4,7,99,8,12,6};

        Mergesort(bob);

        for(int i=0; i< bob.length; i++){
            System.out.print(bob[i]+",");
        }
    }

    public static int[] Mergesort(int[] bob){

        int length = bob.length;
        int mid = bob.length/2;
        if(length <= 1){
            return bob;
        }

        int[] left = new int[mid];
        int[] right = new int[length-left.length];

        for(int i=0; i< mid; i++){
            left[i]=bob[i];
        }
        for(int j=mid; j< length; j++){
            right[j-mid]=bob[j];
        }

        Mergesort(left);
        Mergesort(right);
        merge(left,right, bob);
        return bob;
    }

    //this is merge method
    public static int[] merge(int[] left, int[] right, int[] bob){
        int l= left.length;
        int r = right.length;

        int i=0, j=0,k=0;

        while(i<l && j<r){
            if(left[i]<=right[j]){
                bob[k] = left[i];
                i++; 

            }
            else
            {
                bob[k] = right[j];
                j++;

            }
            k++;
        }

        while(i<l){
            bob[k] = left[i];
            i++;
            k++;
        }
        while(j<r){
            bob[k] = bob[j];
            j++;
            k++;
        }

        return bob;

    }

}

【问题讨论】:

  • 第二部分代码public static int[] merge(int[] left, int[] right, int[] bob){ int l= left.length; int r = right.length; int i=0, j=0,k=0; while(i&lt;l &amp;&amp; j&lt;r){ if(left[i]&lt;=right[j]){ bob[k] = left[i]; i++; } else { bob[k] = right[j]; j++; } k++; } while(i&lt;l){ bob[k] = left[i]; i++; k++; } while(j&lt;r){ bob[k] = bob[j]; j++; k++; } return bob; } }
  • 请将merge() 方法包含在您的实际问题中。
  • @user4660931:您可以使用问题下方的“编辑”链接添加该信息。
  • 当我尝试添加合并方法时,stackoverflow 告诉我我的帖子主要是代码,所以我无法发布它..正在尝试修复它
  • @DavidWallace 它没有。

标签: java sorting merge


【解决方案1】:

我将向您展示如何通过测试/调试快速找出答案,而不仅仅是告诉您答案。你知道,“教人钓鱼”等等 (source)。

所以,让我们测试您的merge 方法。我修改了 main 方法,只合并两个排序数组{1, 3, 5}{2, 4, 6}。我们知道输出应该是{1, 2, 3, 4, 5, 6}

同时,让我们调试。最原始的调试方式称为“printf 调试”,这意味着我们只需在代码中放置大量日志语句,以便我们可以看到每一步的内部状态。无论您的 merge 输出数组被修改,我都添加了日志记录。目标是观察它以不正确/意外的方式被修改的那一刻。

下面是这两个修改的代码:

public class MergeSort {

  public static void main(String[] args) {
    int[] left = {1, 3, 5};
    int[] right = {2, 4, 6};
    int[] merged = {0, 0, 0, 0, 0, 0};
    merge(left, right, merged);
  }

  public static int[] merge(int[] left, int[] right, int[] bob) {
    System.out.print("Before merge: ");
    System.out.println(Arrays.toString(bob));
    int l = left.length;
    int r = right.length;

    int i = 0, j = 0, k = 0;

    while (i < l && j < r) {
      if (left[i] <= right[j]) {
        bob[k] = left[i];
        System.out.print("Merge step 1: ");
        System.out.println(Arrays.toString(bob));
        i++;

      } else {
        bob[k] = right[j];
        System.out.print("Merge step 2: ");
        System.out.println(Arrays.toString(bob));
        j++;

      }
      k++;
    }

    while (i < l) {
      bob[k] = left[i];
      System.out.print("Merge step 3: ");
      System.out.println(Arrays.toString(bob));
      i++;
      k++;
    }
    while (j < r) {
      bob[k] = bob[j];
      System.out.print("Merge step 4: ");
      System.out.println(Arrays.toString(bob));
      j++;
      k++;
    }

    return bob;
  }
}

这是输出:

Before merge: [0, 0, 0, 0, 0, 0]
Merge step 1: [1, 0, 0, 0, 0, 0]
Merge step 2: [1, 2, 0, 0, 0, 0]
Merge step 1: [1, 2, 3, 0, 0, 0]
Merge step 2: [1, 2, 3, 4, 0, 0]
Merge step 1: [1, 2, 3, 4, 5, 0]
Merge step 4: [1, 2, 3, 4, 5, 3]

那么,您的代码中的问题在哪里?显然在“合并步骤 4”或bob[k] = bob[j]; 行中。多么酷啊?通过几个简单的print 调用,我们已经找到了您的错误的确切位置!

【讨论】:

  • 我永远不会这样做!所有现代 IDE 都带有一个调试器,它可以让您查看每一步的所有值,而无需在代码中添加任何内容。习惯于在代码中添加System.out.println 行的人通常无法养成在发现问题后删除它们的习惯。我已经看到太多这些最终出现在生产系统中,因为程序员粗心。没有必要这样做。学习使用调试器。
  • @DavidWallace 我也不会这样做(在大多数情况下)。但这总比什么都不做并期待 SO 为您找到答案要好。更重要的是,我无法在文本帖子中向您展示如何使用调试器,但我可以向您展示如何进行 printf 调试。这通常是每个人学习调试的第一种方式,而 OP 显然需要学习调试。
  • @DavidWallace 和这类的事情在生产系统中占有一席之地。这称为日志记录。日志记录的一个目的是帮助将来进行调试,并且在某些生产系统中,解决新错误的唯一方法是部署一些新的日志行。但这是一个单独的讨论。 OP 显然不是在编写生产代码。 OP 未能掌握这样一个概念,即可以在运行时检查代码的内部状态,并且向 OP 提供答案(而不是教他们缺少什么)相当于向漏气的轮胎添加空气并认为你帮助了轮胎所有者。
  • FWIW,为了找到我发布的答案,我首先在程序中插入了一个 System.out.println(); 语句,当这还不够时,启动调试器并开始检查 @ 每一行中的变量987654333@。我工作的生产代码仍然包含一些人们忘记删除的System.out.println 语句,它们有点令人讨厌。
【解决方案2】:

我相信您的错误在merge() 的这一行中:

        bob[k] = bob[j];

应该是

        bob[k] = right[j];

通过此更改,我得到以下输出:

4,6,7,8,12,99,

【讨论】:

    猜你喜欢
    • 2013-11-21
    • 1970-01-01
    • 2018-05-16
    • 2012-03-15
    • 1970-01-01
    • 2018-01-15
    • 1970-01-01
    相关资源
    最近更新 更多