C++四大常见排序对比

运行结果:

测试代码:

cpp 复制代码
#include <iostream>
#include <vector>
#include <chrono>
#include <iomanip>
#include <random>
#include <algorithm>

using namespace std;
using namespace std::chrono;

//冒泡排序
void bubbleSort(vector<int>& arr)
{
    int n = arr.size();
    for (int i = 0; i < n - 1; i++)
    {
        bool swapped = false;
        for (int j = 0; j < n - i - 1; j++)
        {
            if (arr[j] > arr[j + 1])
            {
                swap(arr[j], arr[j + 1]);
                swapped = true;
            }
        }
        //如果某一趟没有发生交换,说明已经有序
        if (!swapped)
        {
            break;
        }
    }
}

//快速排序
void quickSort(vector<int>& arr, int low, int high)
{
    if (low < high)
    {
        //使用中间位置作为基准,避免在有序/逆序数据下退化导致栈溢出
        int mid = low + (high - low) / 2;
        int pivot = arr[mid];

        //将基准移到最左边,方便移动
        swap(arr[mid], arr[low]);

        int i = low;
        int j = high;

        while (i < j)
        {
            while (i < j && arr[j] >= pivot)
            {
                j--;
            }
            if (i < j)
            {
                arr[i++] = arr[j];
            }
            while (i < j && arr[i] <= pivot)
            {
                i++;
            }
            if (i < j)
            {
                arr[j--] = arr[i];
            }
        }
        arr[i] = pivot;

        quickSort(arr, low, i - 1);
        quickSort(arr, i + 1, high);
    }
}

//快速排序的包装函数,方便统一接口调用
void quickSortWrapper(vector<int>& arr)
{
    if (!arr.empty())
    {
        quickSort(arr, 0, arr.size() - 1);
    }
}

//堆排序
void heapify(vector<int>& arr, int n, int i)
{
    int largest = i;
    int left = 2 * i + 1;
    int right = 2 * i + 2;

    if (left < n && arr[left] > arr[largest])
    {
        largest = left;
    }
    if (right < n && arr[right] > arr[largest])
    {
        largest = right;
    }

    if (largest != i)
    {
        swap(arr[i], arr[largest]);
        heapify(arr, n, largest);
    }
}

void heapSort(vector<int>& arr)
{
    int n = arr.size();
    //构建大顶堆
    for (int i = n / 2 - 1; i >= 0; i--)
    {
        heapify(arr, n, i);
    }
    //逐个提取元素至末尾
    for (int i = n - 1; i > 0; i--)
    {
        swap(arr[0], arr[i]);
        heapify(arr, i, 0);
    }
}

//归并排序
void merge(vector<int>& arr, int left, int mid, int right, vector<int>& temp)
{
    int i = left;
    int j = mid + 1;
    int k = 0;

    while (i <= mid && j <= right)
    {
        if (arr[i] <= arr[j])
        {
            temp[k++] = arr[i++];
        }
        else
        {
            temp[k++] = arr[j++];
        }
    }

    while (i <= mid)
    {
        temp[k++] = arr[i++];
    }

    while (j <= right)
    {
        temp[k++] = arr[j++];
    }

    for (int idx = 0; idx < k; idx++)
    {
        arr[left + idx] = temp[idx];
    }
}

void mergeSortRecursive(vector<int>& arr, int left, int right, vector<int>& temp)
{
    if (left < right)
    {
        int mid = left + (right - left) / 2;
        mergeSortRecursive(arr, left, mid, temp);
        mergeSortRecursive(arr, mid + 1, right, temp);
        merge(arr, left, mid, right, temp);
    }
}

//归并排序的包装函数
void mergeSort(vector<int>& arr)
{
    if (!arr.empty())
    {
        vector<int> temp(arr.size());
        mergeSortRecursive(arr, 0, arr.size() - 1, temp);
    }
}

//数据生成工具
//1: 有序, 2: 逆序, 3: 随机
void generateData(vector<int>& arr, int n, int type)
{
    arr.resize(n);

    // 初始化随机数生成器
    random_device rd;
    mt19937 gen(rd());
    uniform_int_distribution<> dis(0, n);

    for (int i = 0; i < n; i++)
    {
        if (type == 1) // 有序
        {
            arr[i] = i;
        }
        else if (type == 2) // 逆序
        {
            arr[i] = n - i;
        }
        else // 随机
        {
            arr[i] = dis(gen);
        }
    }
}

//核心测试逻辑
//执行算法并返回消耗毫秒数(3次平均)
double testSortAlgorithm(void (*sortFunc)(vector<int>&), const vector<int>& sourceArr)
{
    double totalTime = 0.0;
    int runs = 3; //运行3次求平均

    for (int r = 0; r < runs; r++)
    {
        //每次运行前拷贝原始数据
        vector<int> testArr = sourceArr;

        //记录开始时间
        auto start = high_resolution_clock::now();

        sortFunc(testArr);

        //记录结束时间
        auto end = high_resolution_clock::now();

        //计算耗时 (毫秒)
        duration<double, milli> ms_double = end - start;
        totalTime += ms_double.count();
    }

    return totalTime / runs;
}

int main()
{
    vector<int> sizes = { 100, 1000, 10000, 100000 };
    vector<string> types = { "有序", "逆序", "随机" };

    cout << "开始测试排序算法性能..." << endl;
    cout << "=========================================================================" << endl;
    cout << left << setw(12) << "数据规模"
        << setw(12) << "数据类型"
        << setw(14) << "冒泡(ms)"
        << setw(14) << "快排(ms)"
        << setw(14) << "堆排(ms)"
        << setw(14) << "归并(ms)" << endl;
    cout << "-------------------------------------------------------------------------" << endl;

    //设置浮点数输出格式
    cout << fixed << setprecision(2);

    for (int n : sizes)
    {
        vector<int> sourceArr;

        for (int t = 1; t <= 3; t++)
        {
            //生成原始数据
            generateData(sourceArr, n, t);

            //记录4种算法的时间
            double timeBubble = testSortAlgorithm(bubbleSort, sourceArr);
            double timeQuick = testSortAlgorithm(quickSortWrapper, sourceArr);
            double timeHeap = testSortAlgorithm(heapSort, sourceArr);
            double timeMerge = testSortAlgorithm(mergeSort, sourceArr);

            cout << left << setw(12) << n
                << setw(12) << types[t - 1]
                << setw(14) << timeBubble
                << setw(14) << timeQuick
                << setw(14) << timeHeap
                << setw(14) << timeMerge << endl;
        }
        cout << "-------------------------------------------------------------------------" << endl;
    }

    cout << "测试完成" << endl;

    return 0;
}
相关推荐
云栖梦泽2 小时前
Linux内核与驱动:8.ioctl驱动基础
linux·c++
Allen_LVyingbo2 小时前
量子测量三部曲:投影测量、POVM 与坍缩之谜—从形式主义到物理图像
算法·性能优化·健康医疗·量子计算·空间计算
云栖梦泽2 小时前
Linux内核与驱动:7.从应用层 lseek() 到驱动层 .llseek,Linux 字符设备偏移控制详解
linux·c++
qiqsevenqiqiqiqi2 小时前
位运算 计算
算法
steins_甲乙2 小时前
从0做一个小型内存泄露检测器(2): elf文件的动态链接
c++
甄心爱学习2 小时前
【最优化】1-6章习题
人工智能·算法
charlie1145141912 小时前
通用GUI编程技术——图形渲染实战(二十八)——图像格式与编解码:PNG/JPEG全掌握
开发语言·c++·windows·学习·图形渲染·win32
PD我是你的真爱粉2 小时前
向量数据库原理与检索算法入门:ANN、HNSW、LSH、PQ 与相似度计算
数据库·人工智能·算法
汀、人工智能2 小时前
[特殊字符] 第72课:杨辉三角
数据结构·算法·数据库架构·图论·bfs·杨辉三角