【问题标题】:Merge Sort count number of swaps and compares合并排序计数交换和比较的次数
【发布时间】:2015-07-09 02:50:24
【问题描述】:

我有这个现有的代码,我需要为其添加一个交换和比较计数器。到目前为止,我相信我的计数是正确的,但是我无法让输出不显示每个交换的循环。

public void mergeSort(int[] a, int howMany) {


    if (a.length >= 2) {
        // split array into two halves
        int[] left  = Arrays.copyOfRange(a, 0, a.length/2);
        int[] right = Arrays.copyOfRange(a, a.length/2, a.length);


        // sort the two halves
        mergeSort(left,howMany);
        mergeSort(right, howMany);

        // merge the sorted halves into a sorted whole
        merge(a, left, right);

    }
}




// Merges the left/right elements into a sorted result.
// Precondition: left/right are sorted
public static void merge(int[] result, int[] left, 
                                       int[] right) {
    int i1 = 0;   // index into left array
    int i2 = 0;   // index into right array
   int compCount = 0;
   int swapCount = 0;  
    for (int i = 0; i < result.length; i++) {
        compCount++;
        if (i2 >= right.length ||
           (i1 < left.length && left[i1] <= right[i2])) {
            result[i] = left[i1];    // take from left
            i1++;
           swapCount++;
        } else {
            result[i] = right[i2];   // take from right
            i2++;
           swapCount++;
        }
    }
   //figure this loop issue out System.out.println("merge sort " + compCount + " " + swapCount);
}

【问题讨论】:

  • 您是否尝试在所有递归调用完成后获取交换总数并进行比较?
  • 是的,我正在尝试系统输出结果以了解每种排序方法的工作原理。

标签: java sorting merge compare swap


【解决方案1】:

在包含合并和合并排序方法的类中创建一个全局变量或字段。这将允许方法递增到变量。如果您在方法内部声明,它将保留为局部变量,并且每个递归调用将产生同名但属于不同递归方法调用的不同局部变量。因此,您的代码应如下所示:

public class ClassWithMergeMethodInside
{
    int swapCount;
    int compCount;

    public void mergeSort(int[] a, int howMany) {
        //Since merge sort begins here you may initiliaze the variables here
        swapCount = 0;
        compCount = 0;
        if (a.length >= 2) {
            // split array into two halves
            int[] left  = Arrays.copyOfRange(a, 0, a.length/2);
            int[] right = Arrays.copyOfRange(a, a.length/2, a.length);


            // sort the two halves
            mergeSort(left,howMany);
            mergeSort(right, howMany);

            // merge the sorted halves into a sorted whole
            merge(a, left, right);

        }
    }




    // Merges the left/right elements into a sorted result.
    // Precondition: left/right are sorted
    public static void merge(int[] result, int[] left, 
                                           int[] right) {
        int i1 = 0;   // index into left array
        int i2 = 0;   // index into right array
        //Will not declare counter variables here
        for (int i = 0; i < result.length; i++) {
            compCount++;
            if (i2 >= right.length ||
               (i1 < left.length && left[i1] <= right[i2])) {
                result[i] = left[i1];    // take from left
                i1++;
               swapCount++;
            } else {
                result[i] = right[i2];   // take from right
                i2++;
               swapCount++;
            }
        }
       //figure this loop issue out System.out.println("merge sort " + compCount + " " + swapCount);
    }
}

【讨论】:

  • 我自己之前尝试过这个解决方案,但是我得到了几个无法从静态上下文中引用的错误。
  • 将方法头更改为静态。还将变量更改为静态。
  • 我现在仍然遇到问题我可以输出合并,但我得到了每个循环的 sysout。完成所有操作后,我想要一个简单的比较计数和交换计数。
【解决方案2】:

我认为最优雅的解决方案是使用int 包装类来模拟传递引用。 Java 中的一切都是按值传递,但如果不更改 Object 引用指向的引用,则可以模拟递归调用的按引用传递。

这是一个例子:

import java.util.Arrays; 

public class TestMain
{
  public static void main(String[] args)
  {
    int[] array = new int[]{6, 2, 1, 4, 5, 3};

    IntWrapper countCompare = new IntWrapper();
    IntWrapper countSwap = new IntWrapper();



    MergeSort mSort = new MergeSort();

    mSort.mergeSort(array, countCompare, countSwap);

    System.out.println("Compares: " + countCompare.val);

    System.out.println("Swaps: " + countSwap.val);

    for (int i = 0; i < array.length; i++){
        System.out.print(String.format("%-3d", array[i]));
    }
  }


}

public class IntWrapper{
   int val = 0; 
}

public class MergeSort
{


    public void mergeSort(int[] a, IntWrapper compares, IntWrapper swaps) {


      if (a.length >= 2) {
          // split array into two halves
          int[] left  = Arrays.copyOfRange(a, 0, a.length/2);
          int[] right = Arrays.copyOfRange(a, a.length/2, a.length);


          // sort the two halves
          mergeSort(left, compares, swaps);
          mergeSort(right, compares, swaps);

          // merge the sorted halves into a sorted whole
          merge(a, left, right, compares, swaps);

      }
  }




  // Merges the left/right elements into a sorted result.
  // Precondition: left/right are sorted
  public static void merge(int[] result, int[] left, int[] right, IntWrapper compares, IntWrapper swaps) {
      int i1 = 0;   // index into left array
      int i2 = 0;   // index into right array
     //int compCount = 0;
     //int swapCount = 0;  
      for (int i = 0; i < result.length; i++) {
          //compCount++;
          compares.val++;
          if (i2 >= right.length ||
             (i1 < left.length && left[i1] <= right[i2])) {
              result[i] = left[i1];    // take from left
              i1++;
             //swapCount++;
             swaps.val++;
          } else {
              result[i] = right[i2];   // take from right
              i2++;
             //swapCount++;
             swaps.val++;
          }
      }
     //figure this loop issue out System.out.println("merge sort " + compCount + " " + swapCount);
  }
}

输出:

Compares: 16
Swaps: 16
1  2  3  4  5  6  

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-19
    • 2013-03-10
    • 2016-10-02
    • 2018-05-16
    相关资源
    最近更新 更多