十大排序 C++

在这里插入图片描述
冒泡、选择、插入是基本,笔试快排经常考!

Talk is cheap, show you the code.

// #include <iostream>
// #include <vector>
// #include <algorithm>
// #include <cmath>
#include <bits/stdc++.h>

void bubbleSort(std::vector<int>& arr); // 1、冒泡排序
void selectSort(std::vector<int>& arr); // 2、选择排序
void insertSort(std::vector<int>& arr); // 3、插入排序
void shellSort(std::vector<int>& arr);  // 4、希尔排序
void shellSort2(std::vector<int>& arr); // 假的希尔排序
void mergeSort(std::vector<int>& arr, int left, int right); // 5、归并排序
void quickSort(std::vector<int>& arr, int left, int right); // 6、快速排序
void quickSort2(std::vector<int>& arr, int left, int right); // 效率较低
void heapSort(std::vector<int>& arr);   // 7、堆排序
void sink(std::vector<int>& arr, int index, int len); // 堆排序的 下沉操作
void countSort(std::vector<int>& arr);  // 8、计数排序
void bucketSort(std::vector<int>& arr); // 9、桶排序
void radixSort(std::vector<int>& arr);  // 10、基数排序

int main()
{
    //产生 0-10000 的随机数组
    std::vector<int> data(10000, 0);
    srand((int)time(NULL));
    for (int i = 0; i < 10000; ++i)
        data[i] = rand() % 10000;

    std::cout << "before sort ----- \n";
    for(const int& d : data)
        std::cout << d << '\t';
    std::cout << "\n\n\n\n";

    clock_t start, end;
	start = clock(); //计时开始
    bucketSort(data);
    end = clock();   //计时结束
    
    std::cout << "after sort ----- \n";
    for(const int& d : data)
        std::cout << d << '\t';
    std::cout << "\n\n\n\n";

    std::cout << "sort time ----- " << float((end - start) * 1000 / CLOCKS_PER_SEC) << "ms\n\n\n";
    system("pause");
}

// ***** 冒泡排序 ***** //
// 时间复杂度:O(n2)    空间复杂度:O(1)    稳定排序
void bubbleSort(std::vector<int>& arr)
{
    int len = arr.size();
    for (int i = len - 1; i > 0; --i) //循环(len-1)次
    {
        for (int j = 0; j < i; ++j) //不断将大数交换到最后
        {
            if(arr[j] > arr[j + 1])
            {
                int tmp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = tmp;
            }
        }
    }
}

// ***** 选择排序 ***** //
// 时间复杂度:O(n2)    空间复杂度:O(1)    非稳定排序
void selectSort(std::vector<int>& arr)
{
    int len = arr.size();
    for (int i = 0; i < len; ++i) //循环(len-1)次
    {
        int index = i;
        for (int j = i + 1; j < len; ++j) //每次找出最小的数并放到前面
        {
            if(arr[index] > arr[j])
                index = j;
        }

        int tmp = arr[index];
        arr[index] = arr[i];
        arr[i] = tmp;
    }
}

// ***** 插入排序 ***** //
// 时间复杂度:O(n2)    空间复杂度:O(1)    稳定排序
void insertSort(std::vector<int>& arr)
{
    int len = arr.size();
    for (int i = 1, j; i < len; ++i) //循环(len-1)次
    {
        int curValue = arr[i];
        for (j = i - 1; j >= 0; --j) //往前遍历
        {
            if(curValue < arr[j])
                arr[j + 1] = arr[j]; //后移
            else
                break;
        }

        arr[j + 1] = curValue; //插入
    }
}

// ***** 希尔排序 ***** //
// 时间复杂度:O(nlogn)    空间复杂度:O(1)    非稳定排序
void shellSort(std::vector<int>& arr)
{
    int len = arr.size();
    int gap = len / 2;
    while(gap > 0)
    {
        for (int i = gap, j; i < len; ++i) //插入排序的升级版
        {
            int cur = arr[i];
            for (j = i - gap; j >= 0; j -= gap) //往前遍历
            {
                if(arr[j] > cur)
                    arr[j + gap] = arr[j]; //后移
                else
                    break;
            }

            arr[j + gap] = cur; //插入
        }

        gap /= 2;
    }
}

void shellSort2(std::vector<int>& arr)
{
    int len = arr.size();
    for (int i = len / 2; i > 0; --i)
    {
        for (int j = i; j < len; ++j)
        {
            int k = j - i;
            while(k >= 0 && arr[k] < arr[j]) 
                k -= i;
            if(k >= 0)
            {
                int tmp = arr[j];
                arr[j] = arr[k];
                arr[k] = tmp;
            }
        }
    }
}

// ***** 归并排序 ***** //
// 时间复杂度:O(nlogn)    空间复杂度:O(n)    稳定排序
void mergeSort(std::vector<int>& arr, int left, int right)
{
    // 终止条件,不治而治
    if(left >= right)
        return;

    // 分而治之
    int mid = left + (right - left) / 2;
    mergeSort(arr, left, mid);
    mergeSort(arr, mid + 1, right);

    // 合并
    std::vector<int> tmp(arr);
    int i = left, j = mid + 1;
    for (int k = left; k <= right; ++k)
    {
        if(j > right || (i <= mid && tmp[i] < tmp[j]))
            arr[k] = tmp[i++];
        else
            arr[k] = tmp[j++];
    }
}

// ***** 快速排序 ***** //
// 时间复杂度:O(nlogn)    空间复杂度:O(logn)    非稳定排序
void quickSort(std::vector<int>& arr, int left, int right)
{
    // 终止条件
    if(left >= right)
        return;

    // arr[left] 作为基准
    int i = left + 1; // i在左边,用于找出 大于 基准的数
    int j = right;    // j在右边,用于找出 小于 基准的数
    while (true)
    {
        while(i <= j && arr[i] <= arr[left]) //找到 大于基础的数,停下来,待会移到右边
            ++i;
        while(i <= j && arr[j] >= arr[left]) //找到 小于基础的数,停下来,待会移到左边
            --j;

        // 交换找到的左右两数
        if(i < j)
        {
            int tmp = arr[i];
            arr[i] = arr[j];
            arr[j] = tmp;
        }
        else
        {
            break;
        }
    }

    // 插入基准数
    int tmp = arr[left];
    arr[left] = arr[j];
    arr[j] = tmp;

    quickSort(arr, left, j - 1);
    quickSort(arr, j + 1, right);
}

void quickSort2(std::vector<int>& arr, int left, int right)
{
    if(left >= right)
        return;

    int i, j;
    for (i = left, j = left; j < right; ++j)
    {
        if(arr[j] < arr[right]) //以最右边为基准数
        {
            // 小于基准数则放到左边
            int tmp = arr[i];
            arr[i] = arr[j];
            arr[j] = tmp;
            ++i;
        }
    }

    // 插入基准数
    int tmp = arr[i];
    arr[i] = arr[right];
    arr[right] = tmp;

    quickSort2(arr, left, i - 1);
    quickSort2(arr, i + 1, right);
}

// ***** 堆排序 ***** //
// 时间复杂度:O(nlogn)    空间复杂度:O(1)    非稳定排序
void heapSort(std::vector<int>& arr)
{
    int len = arr.size();
    // 调整数组为堆
    for (int i = (len - 2) / 2; i >= 0; --i)
        sink(arr, i, len);

    // 交换头尾,并执行下沉操作
    for (int i = len - 1; i > 0; --i)
    {
        int tmp = arr[0];
        arr[0] = arr[i];
        arr[i] = tmp;

        sink(arr, 0, i);
    }
}

void sink(std::vector<int>& arr, int index, int len)
{   
    int curVal = arr[index];
    int childIndex = 2 * index + 1;
    while (childIndex < len)
    {
        //大顶堆,对应升序排
        int maxIndex = childIndex;
        if(childIndex + 1 < len && arr[childIndex + 1] > arr[childIndex])
            maxIndex = childIndex + 1;
        
        if(arr[maxIndex] <= curVal)
            break;

        arr[index] = arr[maxIndex];
        index = maxIndex;
        childIndex = index * 2 + 1;
    }
    arr[index] = curVal;
}

// ***** 计数排序 ***** //
// 时间复杂度:O(n+k)    空间复杂度:O(k)    稳定排序
void countSort(std::vector<int>& arr)
{
    // 找到最大最小值
    int minVal = arr[0], maxVal = arr[0];
    for (const int& a : arr)
    {
        if(a < minVal)
            minVal = a;
        if(a > maxVal)
            maxVal = a;
    }

    // 建立临时数组,统计每个值出现的次数
    std::vector<int> countArr(maxVal - minVal + 1, 0);
    for(const int& a : arr)
        ++countArr[a - minVal];

    // 将临时数组拷贝回原数组
    for (int i = 0, index = 0; i < countArr.size(); ++i)
    {
        for (int j = 0; j < countArr[i]; ++j)
        {
            arr[index] = i + minVal;
            ++index;
        }
    }
}

// ***** 桶排序 ***** //
// 时间复杂度:O(n+k)    空间复杂度:O(n+k)    稳定排序
void bucketSort(std::vector<int>& arr)
{
    // 找到最大最小值
    int minVal = arr[0], maxVal = arr[0];
    for (const int& a : arr)
    {
        if(a < minVal)
            minVal = a;
        if(a > maxVal)
            maxVal = a;
    }

    //求差值创建桶,默认桶区间大小为5,遍历数组将每个元素存入对应的桶
    int dValue = maxVal - minVal;
    int bucketNum = dValue / 5 + 1;
    std::vector<std::vector<int>> bucketVec(bucketNum, std::vector<int>());
    for (int i = 0; i < arr.size(); ++i)
    {
        int index = (arr[i] - minVal) * (bucketNum - 1) / dValue;
        bucketVec[index].emplace_back(arr[i]);
    }

    //对桶内元素排序
    for (int i = 0; i < bucketNum; ++i)
        std::sort(bucketVec[i].begin(), bucketVec[i].end());
    
    //把桶内元素汇总到原数组
    int index = 0;
    for (int i = 0; i < bucketNum; ++i)
    {
        for (int j = 0; j < bucketVec[i].size(); ++j)
        {
            arr[index] = bucketVec[i][j];
            ++index;
        }
    }
}

// ***** 基数排序 ***** //
// 时间复杂度:O(kn)    空间复杂度:O(n+k)    稳定排序
void radixSort(std::vector<int>& arr)
{
    //找最大值
    int max = arr[0];
    for (int i = 1; i < arr.size(); ++i)
    {
        if(max < arr[i])
            max = arr[i];
    }

    //计算最大值是几位
    int num = 1;
    while(max / 10 > 0)
    {
        ++num;
        max /= 10;
    }

    //创建10个桶,从个位数开始排序
    std::vector<std::vector<int>> bucketVec(10, std::vector<int>());
    for (int i = 0; i < num; ++i)
    {
        //存入对应桶
        for (int j = 0; j < arr.size(); ++j)
        {
            int index = arr[j] / (int)pow(10, i) % 10;
            bucketVec[index].emplace_back(arr[j]);
        }

        //放回原数组
        int index = 0;
        for (int i = 0; i < 10; ++i)
        {
            for (int j = 0; j < bucketVec[i].size(); ++j)
            {
                arr[index] = bucketVec[i][j];
                ++index;
            }

            bucketVec[i].clear(); //清空以备下次使用
        }
    }
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

木木+江鸟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值