繁体   English   中英

Quicksort可视化?

[英]Quicksort visualization?

我是编程新手,并且希望使用三分位数分割法和3的临界值对quicksort算法进行可视化表示。

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

例如,尝试对该数组应用quicksort:[2、6、3、1、6、5、2、4、8]

使用三位数中位规则,枢轴是最左边,最中心和最右边元素的中位数。 所以2、6和8的中值为6。

下一步是分区:选择枢轴后,将所有小于枢轴的元素移至左侧,将所有元素移至右侧。 完成此操作后,您可以在左侧和右侧分别进行排序。

分区之前:

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

在左侧划分<6 ,在右侧划分>=6

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

要左右排序,请在两侧重复相同的步骤。

我让您发现分区过程的非常细节(真正的划分过程以不同的顺序离开了元素)。

要记住的问题:

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

  • 理想情况下,分区将数组拆分为大小大致相等的两个子数组; 但是大小也会变得非常不相等,从而使算法变慢得多; 三分位数启发式算法不能完全避免该现象;

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

  • 对于小型数组而言,此过程是多余的,这就是为什么建议切换到更简单的方法的原因,在这种情况下,建议使用StraightInsertion或StraightSelection。

您可以将整个排序过程描绘成一个二叉树,其中一个节点保存一个数组,并区分枢轴,并让两个儿子保存子数组。

在此处输入图片说明

所以2,6,8的中值为6。

下一步是将数组划分为左半部分(包含小于6的元素)和右半部分(包含等于或大于6的元素)。然后在每半部分上调用quicksort。

以下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

您可以在核桃木上看到交互式的可视化效果并进行操作。 它使用Dijkstra分区(小于,等于,大于枢轴)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM