您的位置:首页 > 编程语言 > C语言/C++

C++快速排序的实现

2018-03-11 14:00 253 查看
C++快速排序的实现

1、QuickSort.h

/* 初始版本,升序排序 */
/* 时间复杂度:最好O(nlbn),平均O(nlbn),最坏0(n^2)
   空间复杂度:O(lbn) 递归栈最大深度为[lbn] + 1
   不稳定:情况基于每次划分选择的主元。随机化快排得到理论最坏情况的可能性仅为1/(2^n)
/*
* 快排思想:
* 1. 随机选取一个主元作为基准,从待排序记录序列左右两端开始,逐渐向中间靠拢,交替与主元比较、交换
* 左侧记录大于主元则交换,右侧记录大于主元则交换,交换后向中间靠拢
* 最后,主元到达它的最终位置
* 2. 对主元左右两个区域重复上述快速排序过程,结果分别让左右两个区域中的主元到达它们的最终位置
* 同时将待排序记录序列分成更小的待排序区域,再次对每个区域进行一趟快速排序,直到每个区域只有一个记录为止
*/

#ifndef QUICKSORT_H
#define QUICKSORT_H
#include <stdlib.h>

/* 从0开始,n为数组大小 */
int Partition(int arr[], int n)
{
    int pos = 0 + rand() % n;    // 随机选取主元 a + rand() % b = [a, b) 随机一个整数
    int main = arr[pos];       // 记录主元的值

    int low = 0, high = n - 1;
    std::swap(arr[0], arr[pos]);      /*  TODO :将主元跟最低位置的元素交换,这一步很重要 */
    while(low < high)   // 比较完毕之后,主元所处的位置就是low == high
    {
        /* 必须从右边开始,因为要确保low == high时,arr[low]的值必须小于主元,即保证右侧的元素大于等于主元
        若从左边开始,则应先将主元与最高位置的元素交换      */
        while(low < high && arr[high] >= main)  // 找到右边区域比主元小的数
            --high;

        while(low < high && arr[low] <= main)   // 找到左边区域比主元大的数
            ++low;

        if(low < high)
            std::swap(arr[low], arr[high]);
    }

    arr[0] = arr[low];  /* arr[0]保存的是主元的值,而arr[low]的值小于主元 */
    arr[low] = main;	// 主元归位,此处 low == high
    return low;
}

void QuickSort(int arr[], int n)
{
    if(n <= 1)
        return;
    if(n > 1)
    {
        int p = Partition(arr, n);        // 选取一个主元,交换左右区域数据
        /* 去掉注释可以查看快排内部过程 */
        // std::cout << std::endl;
        // for(int i = 0; i < p; ++i)
        //     std::cout << arr[i] << " ";
        // std::cout << "**" << arr[p] << "** ";
        // for(int i = 0; i < n - p - 1; ++i)
        //     std::cout << arr[p + 1 + i] << " ";
        QuickSort(arr, p);                // 对左边区域进行快速排序
        QuickSort(arr + p + 1, n - p - 1);       // 对右边区域进行快速排序
    }
}

#endif // QUICKSORT_H

2、main.cpp

#include <iostream>
#include <stdlib.h>
#include "QuickSort.h"

#define MAX 10           // 随机数的最大数
#define MIN 1            // 随机数的最小数
#define MAXSIZE 10       // 数组大小
#define SORTTIMES 100    // 随机生成数组并进行排序的次数

int main(int argc, char *argv[])
{
    int arr[MAXSIZE];
    int i = SORTTIMES;
    while(i--){
        for(int i = 0; i < MAXSIZE; ++i)
        {
           arr[i] = (MIN + (int)MAX * rand() / (RAND_MAX + 1)); // 生成随机数组
           std::cout << arr[i] << " ";         // TODO : 输出生成的随机数,可注释掉
        }

        QuickSort(arr, MAXSIZE);            // 排序
        std::cout << "\t ==> \t";

        for(int i = 0; i < MAXSIZE; ++i)
            std::cout << arr[i] << " ";
        std::cout << std::endl;
    }
}

测试结果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息