快速排序算法

第7章  快速排序

 此篇博客很早之前写的,格式不够优雅,优化版请移步再谈快速排序


摘要:

        快速排序是一种排序算法,对包含n个数的输入数组,最坏情况运行时间为O(n2)。由于平均性能比较好,期望的运行时间为O(nlgn),且O(nlgn)记号中隐含的常数因子很小,快速排序通常用于排序的最佳的实用选择。

 

7.1 快速排序的描述

快速排序是基于分治模式构思的,具体描述如下:

分解:数组A[p..r]被划分成两个(可能空)子数组A[p..q-1]和A[q+1..r],使得A[p..q-1]中的每个元素都小于等于A(q),而且,小于等于A[q+1..r]中的元素。下标q也在这个划分过程中进行计算。

解决:通过递归调用快速排序,对子数组A[p..q-1]和A[q+1..r]排序。

合并:因为两个子数组是就地排序的,将它们合并不需要操作:整个数组A[p..r]已排序。

 

下面的过程实现快速排序:

QUICKSORT(A, p, r)

             if p < r

                       then q <- PARTITION(A, p, r)

                                QUICKSORT(A, p, q–1)

                                QUICKSORT(A, q+1, r)

为排序一个完整的数组A,最初的调用是QUICKSORT(A,1, length[A])。

 

数组划分:

快速排序算法的关键是PARTITION过程,它对于子数组A[p..r]进行就地重排:

PARTITION(A, p, r)

         x <- A[r]

         i <- p–1

         for j <- p to r–1

                   do if A[j]<= x

                            theni <- i+1

                                     exchangeA[i] <-> A[j]

exchange A[i+1] <-> A[r]

return i+1

 

图7.1展示PARTITION中一个包含8个元素的数组上的操作过程。PARTITION总是选择一个x=A[r]作为主元,并围绕它来划分子数组A[p..r]。随着该过程的执行,数组被划分成四个(可能有空的)区域。

图7.1PARTITION中一个样例数组上的运行过程。(摘自算法导论)

具体执行步骤如下:

a)      i=p-1, j=p, x=A[r]

b)      因为A[i]<=x,i=p,A[i]和A[j]交换

c)      A[j]=7>x,j递增

d)      当A[j]=1时,因为A[i]<=x,i=p+1,A[i]和A[j]交换

e)      当A[j]=3时,因为A[i]<=x,i=p+2,A[i]和A[j]交换

f)       A[j]=5>x,j递增

g)      A[j]=6>x,j递增

h)      j=r,A[r]和A[i+1]交换

 

 

7.2  快速排序算法程序(C++)

//QuickSort.h

 

bool Swap(int *data, int lhs, int rhs);

 

//数组划分

int Partition(int *data, int left, intright)

{

         if(data == NULL || left < 0 || right < 0 || left > right)

                   return-1;

 

         intpivot = data[right];

         inti = left;

         intj = left - 1;

         inttemp = 0;

 

         while(i <= right)

         {

                   if(data[i] <= pivot)

                   {

                            ++j;

                            Swap(data,i, j);

                   }

 

                   ++i;

         }

 

         returnj;

}

 

//快速排序

bool QuickSort(int *data, int left, intright)

{

         if(data == NULL || left < 0 || right < 0 || left >right)

                   returnfalse;

 

         if(left < right)

         {

                   intmid = Partition(data, left, right);

                   QuickSort(data,left, mid - 1);

                   QuickSort(data,mid + 1, right);

         }

 

         returntrue;

}

 

 

//交换数据

bool Swap(int *data, int lhs, int rhs)

{

         if(data == NULL)

                   returnfalse;

 

         inttemp = data[lhs];

         data[lhs]= data[rhs];

         data[rhs]= temp;

 

         returntrue;

}

 

//测试程序Test.cpp

#include <iostream>

#include <stdio.h>

#include "QuickSort.h"

using namespace std;

 

bool Input(int *data, int num);

bool Output(int *data, int num);

 

const int Number = 100;                    //测试数组样例个数

 

int main()

{

         int*data = NULL;

         intnum = Number;

 

         data= new int[num];

 

         Input(data,num);

         Output(data,num);

 

         boolretValue = false;

         if((retValue = MergeSort(data, 0, num - 1)) == false)

         {

                   cout<< "Data Error!" << endl;

                   return-1;

         }

 

         Output(data,num);

 

         delete[]data;

         return0;

}

 

 

//Input Data

bool Input(int *data, int num)

{

         if(data == NULL || num <= 0)

         {

                   returnfalse;

         }

 

         inti = 0;

         for(i = 0; i < num; ++i)

         {

                   data[i]= rand() % num;

         }

 

         returntrue;

}

 

//Output Data

bool Output(int *data, int num)

{

         if(data == NULL || num <= 0)

         {

                   returnfalse;

         }

 

         inti = 0;

         for(i = 0; i < num; ++i)

         {

                   cout<< data[i] << " ";

         }

         cout<< endl;

 

         returntrue;

}

 

快速排序结果:

图7.2 快速排序结果

 

7.3  总结

    快速排序算法因为良好的排序性能,在排序算法中地位显著。在以后的总结中,我会列出排序性能的具体分析过程和直观性能对比,敬请关注。

 

参考文献:

[1] Thomas H.Cormen, Charles E.Leiserson,etc. 算法导论

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值