• 快速排序


    快速排序

    快速排序(Quick Sort)使用分治策略的排序算法,它的算法的基本步骤如下:

    • 1.选择一个基准(需要注意的是基准的选择策略可能影响算法的性能)
    • 2.通过一趟排序将待排序的序列分割成独立的两部分,其中前一部分记录的元素值比基准小,后一部分记录的元素值比基准大,这一步叫做分割
    • 3.通过一趟排序此时基准的位置整好在其排好序的位置
    • 4.分别对第2步得出的两部分进行同样的排序算法,之道整个序列有序

    快排的图解

    下面以数列a={30,40,60,10,20,50}为例,演示它的快速排序过程(如下图)。
    image

    上图只是给出了第1趟快速排序的流程。在第1趟中,设置x=a[i],即x=30。
    (01) 从"右 --> 左"查找小于x的数:找到满足条件的数a[j]=20,此时j=4;然后将a[j]赋值a[i],此时i=0;接着从左往右遍历。
    (02) 从"左 --> 右"查找大于x的数:找到满足条件的数a[i]=40,此时i=1;然后将a[i]赋值a[j],此时j=4;接着从右往左遍历。
    (03) 从"右 --> 左"查找小于x的数:找到满足条件的数a[j]=10,此时j=3;然后将a[j]赋值a[i],此时i=1;接着从左往右遍历。
    (04) 从"左 --> 右"查找大于x的数:找到满足条件的数a[i]=60,此时i=2;然后将a[i]赋值a[j],此时j=3;接着从右往左遍历。
    (05) 从"右 --> 左"查找小于x的数:没有找到满足条件的数。当i>=j时,停止查找;然后将x赋值给a[i]。此趟遍历结束!

    按照同样的方法,对子数列进行递归遍历。最后得到有序数组!

    代码实现

    /**
     * QuickSort
     */
    public class QuickSort {
    
        public static void main(String[] args) {
            int[] array ={30,40,60,10,20,50};
            quickSort(array, 0, array.length-1);
            for (int i : array) {
                System.out.print(i + " ");
            }
        }
        public static void quickSort(int[] array, int start, int end) {
            if (start >= end) {
                return;
            }
            //
            int index = partation(array, start, end);   //获得基准位置
            //对两部分重复排序过程
            if (index > start) {
                quickSort(array, start, index-1);
            }
            if (index < end) {
                quickSort(array, index + 1, end);
            }
        }
        public static int partation(int[] array, int start, int end) {
            int i = start, j = end;
            int index = array[i];                       //确定基准
            while (i < j) {
                while (i < j && array[j] > index) {     //从右边找到第一个比基准小的
                    j --;
                }
                if (i < j) {                            //移动元素到前面
                    array[i++] = array[j];
                }
                while (i < j && array[i] < index) {     //从左到右找到第一个比基准大的
                    i ++;
                }
                if (i < j) {                            //移动元素到后面
                    array[j--] = array[i];
                }
            }
            array[i] = index;                           //放置基准的位置
            return i;
        }
    }
    

    快排分析

    • 最坏时间复杂度
      最坏情况是指每次区间划分的时候,划分的结果都是在基准数字的左边或者右边的序列为空,另一边的序列的元素个数只比排序前少一项(很拗口)!!
      选择的基准是待排序的序列中最小或者最大的那一个!! 此时的时间复杂度是O(n^2)。
    • 最好时间复杂度
      最好情况是指每次区间划分的结果都是基准关键字左右两边的序列长度相等或者相差1,基准是待排序序列的中间值。此时的时间度复杂度是O(nlgn)。
    • 平均时间复杂度
      时间度复杂度是O(nlgn)。
    • 基准关键字的选取
      基准关键字的选取是决定算法性能的关键,常用的基准关键字选取方法如下:
        1. 三者取中
          三者取中是指在当前序列中将首、尾和中间的位置上的元素进行比较,选择三者的中值作为基准关键字,在划分开始前交换序列中第一个和基准关键字的位置。
        1. 取随机数
          取序列左边界和右边界之间的一个随机数作为基准关键字的位置,这种方法得到的快排叫做随机化快速排序。
  • 相关阅读:
    orale 命令行创建&删除数据库
    Oracle 之表分析
    电子商务分销历程
    乐宝分销,人人都是老板
    随手将TPaxScripter 3.0改成了支持Delphi 2009,Delphi 2010,Delphi Xe
    百丽强势布局B2C,20亿铺路改变其销售格局
    顺丰开通B2C商城,快递业欲抢多一寸电商蛋糕
    Exchange环境搭建心得
    c# 添加外部程序集相对引用问题
    Entity Framework Code First 学习
  • 原文地址:https://www.cnblogs.com/chailinbo/p/9318188.html
Copyright © 2020-2023  润新知