【问题标题】:How to count comaprisons and swaps in Quicksort in Java?如何在 Java 中的快速排序中计算比较和交换?
【发布时间】:2017-04-11 22:12:33
【问题描述】:

我有一个使用 Quicksort 对 int 数组进行排序的简单方法。我不知道如何正确计算交换和比较的次数,因为算法是递归的:

public void quicksort(int tablica[], int x, int y) {
    int i,j,v,temp;
    i=x;
    j=y;
    int swaps=0;
    int comparisons=0;
    v=tablica[(x+y) / 2];
    while (i<=j)
    {
        while (tablica [i] <v)
        {
            i++;
        }
        while (tablica [j] >v)
        {
            j--;
        }
        if (i<=j){
            temp = tablica [i];
            tablica [i]=tablica[j];
            tablica [j] = temp;
            i++;
            j--;
            swaps++;
        }
        comparisons++;
    }
    if (x<j)
        quicksort(tablica,x,j);
    if (i<y)
        quicksort(tablica,i,y);
    System.out.println("Comparisons: " + comparisons);
    System.out.println("Swaps: " + swaps);
}

用小(10 个整数)数组运行它会返回:

Comparisons: 1
Swaps: 1
Comparisons: 1
Swaps: 1
Comparisons: 2
Swaps: 2
Comparisons: 1
Swaps: 1
Comparisons: 1
Swaps: 1
Comparisons: 1
Swaps: 1
Comparisons: 2
Swaps: 1
Comparisons: 4
Swaps: 4

如何正确操作?

【问题讨论】:

  • 例如,您可以将变量定义为字段'。

标签: java sorting quicksort


【解决方案1】:

改为定义一个类变量,并在每次运行快速排序方法时更新类变量。

例子

public class example {
  private int swaps=0;
  private int comparisons=0;

  public void quicksort(int tablica[], int x, int y) {
    int i,j,v,temp;
    i=x;
    j=y;

    v=tablica[(x+y) / 2];
    while (i<=j)
    {
        while (tablica [i] <v)
        {
            i++;
        }
        while (tablica [j] >v)
        {
            j--;
        }
        if (i<=j){
            temp = tablica [i];
            tablica [i]=tablica[j];
            tablica [j] = temp;
            i++;
            j--;
            swaps++;
        }
        comparisons++;
    }
    if (x<j)
        quicksort(tablica,x,j);
    if (i<y)
        quicksort(tablica,i,y);
    System.out.println("Comparisons: " + comparisons);
    System.out.println("Swaps: " + swaps);
  }
}

【讨论】:

  • 我得到了正确的(我认为)结果,但“Comparisons: 21 Swaps: 18”仍然打印了多次
  • 在调用快速排序方法后将打印语句移至。
  • 只需将最后两行打印移出快速排序方法并进入main(在您调用快速排序之后),您将获得一份带有最终结果的打印件。 @filiard
【解决方案2】:

您可以使用 AtomicInteger 通过引用传递您的计数器。与使用类变量相反,这种方法是线程安全的,并且允许您同时执行多种排序,同时保持您的统计数据分开。

重新定义你的方法签名:

public void quicksort(int tablica[], int x, int y, AtomicInteger comparisons, AtomicInteger swaps) {

... 并在每次执行交换或比较时增加值。改变这个:

swaps++;

...到这个:

swaps.incrementAndGet();

...并改变这个:

comparisons++;

...到这个:

comparisons.incrementAndGet();

最后,更新你的递归调用:

if (x<j)
    quicksort(tablica,x,j, comparisons, swaps);
if (i<y)
    quicksort(tablica,i,y, comparisons, swaps);

编辑:当你想调用快速排序时:

AtomicInteger comparisonCounter = new AtomicInteger(0);
AtomicInteger swapCounter = new AtomicInteger(0);
quicksort(tablica, x, y, comparisonCounter, swapCounter);

// now you can print out the total number of swaps and comparisons
// using swapCounter.get() and comparisonCounter.get()

【讨论】:

  • 现在如何调用这个方法,有两个AtomicIntegers?以前是这样的:quicksort (tablica, 0, tablica.length-1, );但现在我必须添加我没有的 AtomicIntegers。
  • 已编辑以演示如何调用快速排序。
猜你喜欢
  • 2015-05-21
  • 2014-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-08
  • 2019-04-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多