快速排序基本思想:通过一趟排序将要排序的数据分为两部分,其中一部分小于另外一部分,再分别对每部分进行分割,直到不能分割为止。划分的关键是找出基准记录所在的位置。
快速排序使用分治策略,即将较大规模的问题分解为若干个较小规模结构相似的问题。
快速排序原理:
设当前待排序的无序区为R[low,...,high]。
(1)分解
在R[]low,...high]中任选一个记录(pivot.key)作为基准(pivot),以此基准将数列划分为左右两个区间R[low,...,pivotpos-1]和R[pivotpos+1,...,high],并且满足左区间所有的记录的关键字都小于等于基准记录的关键字(pivot.key),右区间所有记录的关键字都大于等于基准记录的关键字(pivot.key)。基准记录的位置用pivotpos表示。
(2)递归
通过递归调用快速排序分别对左右两个区间进行排序。
排序过程实质上是找出基准所在位置的过程。
(1)设置指针i,j分别指向R[low]和R[high],设置temp记录pivot.key。从R[j]往左找,直到找出比pivot.key小的记录R[j],将R[j]的关键字赋给R[i]。//将关键字小于pivot.key的记录放在左区间内
(2)接着从R[i]往右找,直到找到比pivot.key大的记录R[i],将R[i]的关键字赋值给R[j]。//将关键字大于pivot.key的记录放在右区间内
(3)循环上述(1)(2)两个过程,直到i,j重合。将pivot.key赋值给重合的位置R[i]或R[j]。
(3)合并
快速排序伪代码实现:
void QuickSort(SeqList R,int low,int high){
int pivotpos;//记录基准所在的位置
if(low<high){//当区间长度大于1时进行排序
pivotpos = Partition(R,low,high);
QuickSort(R,low,pivotpos-1);
QuickSort(R,pivotpos+1,high);
}
}
int Partition(SeqList R, int low, int high){
int i= low;
int j= high;
int temp= R[low];
while(i<j){
//从R[j]往右找,找到比temp小的数字,将其放到右区间内
while(R[j]>=temp&&i<j){
j--;
}
if(i<j)
R[i]=R[j];
//从R[i]往左找,直到找到比temp大的数字,将其放到左区间内
while(R[i]<=temp&&i<j){
i++;
}
if(i<j)
R[j]=R[i];
}
R[i]= temp;//把pivot插入到合适的位置
return i;//返回pivot的位置
}