【问题标题】:Quicksort visualization?快速排序可视化?
【发布时间】:2015-07-02 13:53:35
【问题描述】:

我对编程还很陌生,我想要一些快速排序算法的可视化表示,使用中位数为三的分区和截断为 3。

我想看看整个迭代过程,因为 Java 算法对我来说很难理解。

例如,尝试对这个数组应用快速排序:[2, 6, 3, 1, 6, 5, 2, 4, 8]

对于三中位数规则,枢轴是最左边、中间和最右边元素的中间值。所以 2、6 和 8 的中位数是 6。现在呢?

【问题讨论】:

标签: java algorithm sorting visualization quicksort


【解决方案1】:

您可以在the walnut 上查看并使用交互式可视化。它使用 Dijkstra 分区(小于、等于、大于枢轴)。

【讨论】:

    【解决方案2】:

    下一步是分区:当您选择了一个枢轴时,将所有小于该枢轴的元素向左移动,所有大于该枢轴的元素向右移动。完成后,您可以分别在左侧和右侧进行排序。

    分区前:

    [2,6,3,1,6,5,2,4,8]
    

    分割左边的<6,右边的>=6

    [2,3,1,5,2,4] [6,6,8]
    

    要左右排序,请在两边重复相同的过程。

    我让你发现分区过程的细节(真正的以不同的顺序留下元素)。

    要记住的问题:

    • 分区后,两边必须至少保留一个元素,否则过程会永远循环(更糟糕的是,剩下的唯一元素可能是枢轴);

    • 理想情况下,分区将数组分成大小大致相等的两个子数组;但也可能出现非常不等的大小,使算法慢得多;三个启发式的中值并不能完全避免这种现象;

    • 算法以递归方式编写(排序函数调用自身)。在对两个子数组进行排序时,从最小的开始,这样嵌套调用的数量就最小化了。这很重要;

    • 这个过程对于小数组来说是多余的,这就是为什么建议切换到更简单的方法,比如在这种情况下的 StraightInsertion 或 StraightSelection。

    您可以将整个排序过程描绘成一棵二叉树,其中一个节点持有一个数组,其中枢轴是不同的,并且有两个儿子持有子数组。

    【讨论】:

    • 您的回答对我来说最有意义。如果我解释正确,请告诉我。你选择一个中位数。将小于中位数的数字向左排序,大于中位数的数字向右排序。然后你将左右分开,并通过选择一个中值并从左到右排序来执行相同的过程。两者都完成后,您将它们与原始中位数合并在一起。它是否正确?这种解释似乎有效,所以我不确定。
    • 确切地说,您不会将数字左右“排序”,而是将它们左右分区(这意味着顺序无关紧要);分区后,对两个子数组进行排序; “合并”是无操作的,因为元素已经在正确的位置;并且枢轴元素没有被特殊处理:它只是属于子数组之一。
    • 所以我尝试对此进行排序:{3,1,4,1,5,9,2,6,5,3,5}。中位数为 5。{3,1,4,1,2,3|5|5,9,6,5}。对于 {3,1,4,1,2,3} 中位数为 3,因此使用相同的左右方法会变成 {1,1,2,3,3,4}。对于 {5,9,6,5},中位数为 5,但它转换为未排序的子数组:{5,5,9,6}。什么地方出了错?同样在您的视觉中,它是否遍历以确保它已排序?它如何知道子数组是否已排序?检查它是否已排序或进行另一个快速排序会使其效率低下。
    • 手工一步步检查。在调试期间,您还可以添加对分区条件的检查。
    • 一步一步到底是什么意思?
    【解决方案3】:

    所以 2,6,8 的中位数是 6。现在呢?

    下一步是将数组划分为左半部分,包含小于 6 的元素,右半部分包含等于或大于 6 的元素。然后我们对每一半调用快速排序。

    以下 Java 程序实现快速排序,显示排序前后的每个子数组。它还显示中位数的选择。

    import java.io.*;
    
    public class Quicksort {
      void swap(int[] data, int i, int j) {
        int t = data[i];
        data[i] = data[j];
        data[j] = t;
      }
    
      void display(int[] data, int left, int right) {
        for (int i = 0; i < right; ++i) {
          System.out.print(i < left ? "  " : " "+data[i]);
        }
        System.out.println();
      }
    
      //--- in-place implementation with median-of-three pivot
      int quicksort(int[] data, int left, int right, int callId) {
        int saveCallId = callId;
        System.out.print(callId+". sorting:");
        display(data, left, right);
        if (left+1 >= right) {
          System.out.print("  "+saveCallId+". result:");
          display(data, left, right);
          return callId;
        }
        int ai = left, bi = (left+right)/2, ci = right-1, pos;
        int a = data[ai], b = data[bi], c = data[ci];
        if (a < b) {
          if (c < a) {
            pos = ai;
          } else if (c < b) {
            pos = ci;
          } else {
            pos = bi;
          }
        } else {
          if (c < b) {
            pos = bi;
          } else if (c < a) {
            pos = ci;
          } else {
            pos = ai;
          }
        }
        int pivot = data[pos];
        System.out.println("   median of ["+a+", "+b+", "+c+"] is "+pivot);
        swap(data, right-1, pos);
        int tail = left;
        for (int i = left; i != right-1; ++i) {
          if (data[i] < pivot) {
            swap(data, tail, i);
            ++tail;
          }
        }
        swap(data, right-1, tail);
        callId = quicksort(data, left, tail, ++callId);
        callId = quicksort(data, tail+1, right, ++callId);
        System.out.print("  "+saveCallId+". result:");
        display(data, left, right);
        return callId;
      }
    
      public static void main(String[] args) {
        int[] data = new int[]{ 2, 6, 3, 1, 6, 5, 2, 4, 8 };
        new Quicksort().quicksort(data, 0, data.length, 0);
      }
    }
    

    对于输入案例{ 2, 6, 3, 1, 6, 5, 2, 4, 8 },输出为:

    0. sorting: 2 6 3 1 6 5 2 4 8
       median of [2, 6, 8] is 6
    1. sorting: 2 3 1 5 2 4
       median of [2, 5, 4] is 4
    2. sorting: 2 3 1 2
       median of [2, 1, 2] is 2
    3. sorting: 1
      3. result: 1
    4. sorting:     2 3
       median of [2, 3, 3] is 3
    5. sorting:     2
      5. result:     2
    6. sorting:        
      6. result:        
      4. result:     2 3
      2. result: 1 2 2 3
    7. sorting:           5
      7. result:           5
      1. result: 1 2 2 3 4 5
    8. sorting:               6 8
       median of [6, 8, 8] is 8
    9. sorting:               6
      9. result:               6
    10. sorting:                  
      10. result:                  
      8. result:               6 8
      0. result: 1 2 2 3 4 5 6 6 8
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-03-29
      • 2012-09-09
      • 1970-01-01
      • 2020-08-14
      • 2021-07-21
      • 1970-01-01
      • 2016-12-23
      相关资源
      最近更新 更多