编程珠玑之快速排序

来源:互联网 发布:天勤网络 编辑:程序博客网 时间:2024/06/02 06:24
我们将需要划分的目标区间定位[l, u]。
首先给定目标值t = x[l]。我们需要重新组织x[l...u],使得所有小于t的元素都在m的一端,所有大于t的元素在m的另一端。
初始时m = l,我们将i从l+1一直遍历到u,代码在检测第i个元素时必须考虑两种情况。如果x[i]>=t,那么一切正常,不变式为真;如果x[i]<t,可以通过使m增加1(指向小元素的新位置)重新获得不变式,然后交换x[i]和x[m]。

void q_sort_ori(int *a, int low, int high){if (low < high){int m = low;for(int i = low + 1; i <= high; i++){int tmp = a[i];if(tmp < a[low]){swap(a[++m],a[i]);}}swap(a[m],a[low]);for(int i = 0; i <= 7; i++)cout<<a[i]<<" ";cout<<endl;q_sort_ori(a,low,m-1);q_sort_ori(a,m+1,high);}}

下标i和j初始化为待划分数组的两端。主循环中有两个内循环,第一个内循环将i向右移过小元素,遇到大元素时停止;第二个内循环将j向左移过大元素,遇到小元素时停止。然后主循环测试这两个下标是否交叉并交换它们的值。这样做虽然交换的次数增加了,但却将所有元素都相同的最坏情况变成了差不多需要nlog2n次比较的最好情况
void qsort2(int *a, int low, int high) {    if (low < high) {        int i = low + 1;        int j = high;        int tmp = a[low];        while (i <= j) {            while (i <= high && a[i] < tmp) {                i++;            }            while (a[j] > tmp) {                j--;            }            if (i <= j) {                swap(a[i], a[j]);            }        }        swap(a[low], a[j]);        for(int i = 0; i <= 7; i++)cout<<a[i]<<" ";cout<<endl;        qsort2(a, low, j - 1);        qsort2(a, j + 1, high);    }}

测试代码
int main(){int a[] = {55,41,59,26,53,58,97,93};qsort2(a,0,7);for(int i = 0; i <= 7; i++)cout<<a[i]<<" ";}