快速排序

1.思想

  • 快速排序采用的思想是分治思想。(Divide-And-Conquer)

2.基本分析

  • 首先,假设所要排序的数字存储在数组S中,
  • 然后对数组进行分区移位操作即基准左边区域的都是小于基准的,右边区域的都是大于基准的,
  • 然后将基准放在两区域分离的边界中心。

3.举个例子:2 4 9 3 6 7 1 5

  • 首先用2当作基准,使用i j两个指针分别从两边进行扫描,把比2小的元素和比2大的元素 分开
  • 首先比较2和5,5比2大,j左移

    • 2基准 【2 】4 9 3 6 7 1 5

    • 2基准【2】 4 9 3 6 7 1 5 比较2和1,1小于2,所以把1放在2的位置从左 边扫描

    • 2基准1 4 9 3 6 7 【1】 5 比较2和4,4大于2,因此将4移动到后面

    • 2 基准1 【4】9 3 6 7 4 5 比较2和7,2和6,2和3,2和9,全部大于2,满足条件,因此不变

    • 经过第一轮的快速排序,元素变为下面的样子[1] 2 [4 9 3 6 7 5]

    • 将两区域的进行排序,左边一个元素,有序。右边进行快速排序,递归进行。

void quicksort(int a[], int left, int right){
        if(left < right){
                int key = a[left];
                int low = left;
                int high = right;
                while(low < high){
                        while(low < high && a[high] > key){
                                high--;
                        }
                        a[low] = a[high]; //a[high]已经空下来
                        while(low < high && a[low] < key){
                                low++;
                        }
                        a[high] = a[low];  //a[low]已经空下来
                }                
                a[low] = key;//中间数值省去返回值
                quicksort(a,left,low-1);
                quicksort(a,low+1,right);
        }
}

4.总结

  • 快速排序的时间主要耗费在划分操作上,对长度为k的区间进行划分,共需k-1次关键字的比较。

  • 最坏情况是每次划分选取的基准都是当前无序区中关键字最小(或最大)的记录,划分的结果是基准左边的子区间为空(或右边的子区间为空),而划分所得的另一个非空的子区间中记录数目,仅仅比划分前的无序区中记录个数减少一个。时间复杂度为O(n*n)

  • 在最好情况下,每次划分所取的基准都是当前无序区的”中值”记录,划分的结果是基准的左、右两个无序子区间的长度大致相等。总的关键字比较次数:O(nlgn)

  • 尽管快速排序的最坏时间为O(n2),但就平均性能而言,它是基于关键字比较的内部排序算法中速度最快者,快速排序亦因此而得名。它的平均时间复杂度为O(nlgn)。

  • 上述算法没有返回值发现有点问题,下面是一个有返回值的,更能体现分治法。
void QuickSort(ElemType a[],int low, int high){

    if(low < high){          //递归跳出条件

 //               Partition()就是划分操作,将表划分为两个子表
      int pivotpos=Partiton(a,low,high);

       Quicksort(a,pivotpos+1,high);            
}

int Partiton(EleType a[],int low ,int high){
    ElemType piot = a[low] ;        //将当前表的第一个元素设为中枢
    while(low < high){
        while( low < high&&a[high] >= pivot )
              --high;
        a[low] = a[high];         //比中枢小的移到左边
        while(low < high&&a[low] <= pivot)
              ++low;
        a[high] = a[low];        //比中枢大的移到右边
    }
    a[low] = pivot;
    return low;中枢的位置
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值