美文网首页
快速排序

快速排序

作者: MinkChannel | 来源:发表于2016-07-26 12:10 被阅读25次

    快速排序

    思想

    快速排序采用的思想是分治思想。
    快速排序是找出一个元素(理论上可以随便找一个)作为基准(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部分,小于基准值的放一列,等于基准值的放一列,大于基准值的放一列

    相关文章

      网友评论

          本文标题:快速排序

          本文链接:https://www.haomeiwen.com/subject/udunjttx.html