快速排序

快速排序是C.R.A.Hoare提出的一种划分交换排序。它采用了一种分治的策略。

分治法基本思想:将原问题分解成若干个规模更小但结构与原问题相似的子问题,递归的解决这些子问题,然后将子问题的解组合为原问题的解。

快速排序:设当前待排序数组为array[low..high]

(1)分解

在array[low..high]中任选一个记录作为基准(一般以第一个元素为基准),以此基准将当前无序数组划分为左右两个较小的子区间array[low..pivotpos-1]和array[pivotpos+1..high],并使左子区间中的所有记录的关键字都小于等于基准记录的关键字。右边子区间的所有记录的关键字都大于等于基准记录的关键字。基准则位于正确的位置。划分的关键是要求出基准记录所在的位置。

(2)求解

通过递归调用快速排序对左右子区间快速排序。

(3)组合

递归调用结束时,其左右子区间已经有序,就无需在做什么。

快速排序算法:

 1 void QuickSort(SeqList array, int low, int high)
 2 {//对array[low..high]快速排序
 3     int pivotpos;     //划分后基准记录的位置
 4     if(low<high)    //仅当区间长度大于1时才需排序
 5     {
 6         privotpos = Partition(array, low, high);
 7         //对array[low..high]做划分
 8         QuickSort(array, low, pivotpos-1);    //对左区间递归排序
 9         QuickSort(array, pivotpos+1, high);//对右区间递归排序
10     }
11 }

对整个数组排序只需调用QuickSort(array, 1, n)即可。

划分算法Partition

(1)设置两个指针i,j,它们的初始值分别为区间的下界和上界,即i=low,i=high;选取第一个元素作为基准记录,将它保存在pivotpos中。

(2)令j自high起向左扫描,直到遇到第一个比pivotpos.key小的记录array[j],将array[j]移动到i位置,使关键字小于基准的记录移动到基准的左边,然后令i指针自i+1位置开始向右扫描,直到找到第一个比pivotpos.key大的记录array[i],将array[i]移动到j所指的位置上,相当于实现array[i]和基准array[j]的交换,是关键字大于基准的记录移动到基准的右边。接着令指针j自位置j-1开始向左扫描,如此交替改变方向,从两端各自往中间靠拢,直至i=j时,i便是基准pivot的最终位置,将pivot放到此位置就完成了一次划分。

划分算法代码:

int Partition(SeqList array, int i, int j)
{//调用Partition时对array[low..high]做划分并返回基准所在位置
    ReceType pivot = array[i];//用区间的第一个记录作为基准
    while (i<j)//从区间两端交替向中间扫描,直至i=j为止
    {
        while(i<j && array[j] >= pivot)
            j--;//从右向左扫描,查找第一个关键字小于pivot的记录array[j]
        if(i<j)
            array[i++] = array[j];
        while(i<j && array[i] <= pivot)
            i++;//从左向右扫描,查找第一个关键字大于pivot的记录array[i]
        if(i<j)
            array[j--] = array[i];
    }
    array[i] = pivot;    //基准记录已被最后定位
    return i;
}

时间复杂度:快速排序是一种不稳定的排序方法,平均时间复杂度O(nxlgn/lg2),最差情况时间复杂度为O(n*n)。

posted @ 2012-10-18 11:32  Rookie_h  阅读(163)  评论(0编辑  收藏  举报