【问题标题】:Java - Mergesort countingJava - 合并排序计数
【发布时间】:2010-10-01 21:19:12
【问题描述】:

我做了一个合并排序,它与两个已经创建的选择和插入排序并列,它们都计算比较,以便在执行时程序说明哪些方法更快。

  1. 我不知道如何在我的合并集中实现计数
  2. 我真的不知道它是否工作正常,或者我是否只是显示一个先前已经排序的数组,该数组是通过选择或插入在其上方进行排序的。我认为这是因为我无法调用选择和插入的方法。 (您将在下面看到)

到目前为止,我将发布完整的代码,以便您了解选择和插入以及它们是如何使用的。

Arraysort.java


public class ArraySort {
   private long[] a;                 // ref to array a
   private int nElems;               // number of data items

   public ArraySort(int max)          // constructor
      {
      a = new long[max];                 // create the array
      nElems = 0;                        // no items yet
      }

   public void Clone(ArraySort c)      // c is another array
      {
      c.nElems = this.nElems;                                 // Copy nElems
      System.arraycopy(this.a, 0, c.a, 0, this.nElems);       // Copy elements
      }

   public void insert(long value)    // put element into array
      {
      a[nElems++] = value;             // insert value
      }

   public String toString()             // displays array contents
      {
      String res="";
      for(int j=0; j<nElems; j++)       // for each element,
         res = res + a[j] + " ";        // append it to res
      return res;
      }

   private int insertOrder(int n, long temp) { // insert temp into a[0..(n-1)]
                                                  // and keep a[0..n] sorted.
       int count = 0;
       while (n>0) {
           count++;                       // count next comparison
           if (a[n-1] > temp)   {         // until one is smaller,
              a[n] = a[n-1];              // shift item to right
              --n;                        // go left one position
           } else break;
       }
       a[n] = temp;                      // insert marked item
       return count;
   }

   public int insertionSort() {
       int count = 0;
       for (int n=1; n<nElems; n++)  
              count += insertOrder(n, a[n]);   // insert a[n] into a[0..(n-1)]
       return count;
   } // end insertionSort()

   private void swap(int one, int two) {
      long temp = a[one];
      a[one] = a[two];
      a[two] = temp;
   }

   public int selectionSort() {
      int out, in, max, count=0;

      for(out=nElems-1; out > 0; out--) {  // outer loop
         max = out;                        // max is maximum item's index
         for(in=0; in<out; in++) {          // inner loop
            if(a[in] > a[max] )            // if max is smaller,
                max = in;                  // we have a new max
            count++;                       // count one comparison
         }
         swap(out, max);                   // swap them
      }  // end for(out)
      return count;
   }  // end selectionSort()

   public void mergeSort() {
       long[] ws = new long[nElems];
       recMergeSort(ws, 0, nElems-1);
   }

   public void recMergeSort(long[] ws, int lower, int upper) {
       if (lower == upper)
           return;
       else {
           int mid = (lower + upper) / 2;    //find midpoint
           recMergeSort(ws, lower, mid);    //sort lower
           recMergeSort(ws, mid+1, upper);    //sort upper
           merge(ws, lower, mid+1, upper);    //merge
       }

   }

   public void merge(long[] ws, int lowPtr, int highPtr, int upper) {
       int j = 0;
       int lower = lowPtr;
       int mid = highPtr-1;
       int n = upper-lower+1;        //# of items

       while(lowPtr <= mid && highPtr <= upper)
             if( a[lowPtr] < a[highPtr] )
                ws[j++] = (int) a[lowPtr++];
             else
                ws[j++] = (int) a[highPtr++];

          while(lowPtr <= mid)
             ws[j++] = (int) a[lowPtr++];

          while(highPtr <= upper)
             ws[j++] = (int) a[highPtr++];

          for(j=0; j<n; j++)
             a[lower+j] = ws[j];

   }

   public void display() {
       for(int j=0; j<nElems; j++) {
           System.out.print(a[j] + " "); }
       System.out.println("");
       }


//end
}  

SortComparison.java

import java.util.*;

public class SortComparison {

   public static void main(String[] args) {

      int count, maxSize = 100;      // array size
      ArraySort arr, carr;           // reference to array
      arr = new ArraySort(maxSize);  // create the arrays
      carr = new ArraySort(maxSize);


      // insert some random numbers
          Random generator = new Random();
      for (int i = 0; i < 20; i++) {
         arr.insert(Math.abs(generator.nextInt())%maxSize);
      }

      System.out.println("Before sort: " + arr);    // display items

      arr.Clone(carr);
      count = carr.insertionSort();          // insertion-sort a clone of arr
      System.out.println("\nInsert sort: \n" + carr + " ### Comparisons: " + count);                  

      arr.Clone(carr);
      count = carr.selectionSort();          // selection-sort a clone of arr
      System.out.println("\nSelect sort: \n" + carr + " ### Comparisons: " + count); 

      carr.mergeSort();
      System.out.println("\nMerge sort: ");
      carr.display();



 }

}

您可以通过选择和插入来查看应该如何调用事物,返回计数。

【问题讨论】:

  • 我是否正确地假设您在数据结构和算法课程的第 4 周?
  • Math.abs(generator.nextInt())%maxSize 应该写成generator.nextInt(maxSize)

标签: java sorting merge


【解决方案1】:

除了排序数组之外,还有多种方法可以返回计数。您可以将计数或数组存储为类变量。您可以创建一个封装计数和数组的对象。如果您保证记住第一个元素是计数,而不是排序的一部分,您甚至可以将计数添加到数组的前面(这可能是个坏主意)。

在担心计算比较次数之前,您可能希望通过再次复制数组来检查您的排序是否正确。

【讨论】:

  • 归并排序中的比较公式是什么?它是否递归是否重要?我觉得它并不总是一个确定的数字,因为有最好的情况和最坏的情况。
  • 嗯,我实际上是错的。所需的比较次数确实会随着输入的顺序而变化。只有合并排序中的交换次数是恒定的。我已经编辑了我的答案以反映这一点。对不起!
  • 如果您了解渐近分析(大 O 表示法),您会注意到最坏情况和最佳情况的比较顺序是相同的,因为最佳情况只是最坏情况乘以常数。正是这个常数随着数组的初始顺序而变化。无论算法是递归还是扁平化,都是如此。
猜你喜欢
  • 2011-03-23
  • 1970-01-01
  • 2021-08-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-19
  • 2017-03-19
相关资源
最近更新 更多