快速排序

2016-07-26  本文已影响25人  MinkChannel

快速排序

思想

快速排序采用的思想是分治思想。
快速排序是找出一个元素(理论上可以随便找一个)作为基准(pivot),然后对数组进行分区操作,使基准左边元素的值都不大于基准值,基准右边的元素值 都不小于基准值,如此作为基准的元素调整到排序后的正确位置。递归快速排序,将其他n-1个元素也调整到排序后的正确位置。最后每个元素都是在排序后的正 确位置,排序完成。所以快速排序算法的核心算法是分区操作,即如何调整基准的位置以及调整返回基准的最终位置以便分治递归。

总结:该方法的基本思想是:
1.先从数列中取出一个数作为基准数。
2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。
3.再对左右区间重复第二步,直到各区间只有一个数。

关键代码:
切分:

private static int partotion(int[] a,int l,int h){
    int i = l; j = h + 1;
    int v = a[l];
    while(true){
        while(a[++i] <= v) if(i == hi) break;
        while(a[--j] > v) if(j == l) break;
        if(i >= j) break;
        exch(a,i,j);
    }
    exah(a,l,j);
    return j;
}

算法实例(第一步的切分详解)

46 15 82 90 30 56 17 95 选择46 作为基准值,i = 0, j = 7

i = 1 j = 7

46 15 30 82 90 56 17 95 15 < 46, 不需要交换,移动 i, i = 2

i = 2 j = 7

46 15 30 82 90 56 17 95 30 < 46, 不需要交换,移动 i , i = 3

i = 3 j = 7

46 15 30 82 90 56 17 95 82 > 46, 开始移动j

i = 3 j = 7

46 15 30 82 90 56 17 95 95 > 46, 不需要交换,移动 j , j = 6

i = 3 j = 6

46 15 30 17 90 56 82 95 17 < 46, 交换82 和 17,移动j

i = 3 j = 5
                 
                 
 46 15 30 17 90 56 82 95 90 > 46, 开始移动j

i = 4 j = 5

46 15 30 17 90 56 82 95 56 > 46, 不需要交换,移动 j , j = 4

i = j = 4
               
                这时i = j =4 把46 放到第4个元素中去
15 30 17 46 90 56 82 95

i = j = 4, 这样序列就这样分割成了两部分,左边部分{15, 30, 17} 均小于 基准值(46);右边部分 {90 56 82 95},均大于基准值。这样子我们就达到了分割序列的目标。在接着对子序列用同样的办法进行分割,直至子序列不超过一个元素,那么排序结束,整个序列处于有序状态。

算法改进:

1:切换到插入排序: 原因:对于小数组来说,快速排序比插入排序慢
2:三取样切分:取数组的一部分元素的中位数来做为基准值
优点:这样切分会更好
缺点:需要计算中位数
3:熵最优的排序:
将数组切分为3部分,小于基准值的放一列,等于基准值的放一列,大于基准值的放一列

上一篇下一篇

猜你喜欢

热点阅读