Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

计数排序

  • 全称 Counting sort

  • 特点

    • 稳定
    • 时间复杂度
      • O(n + w),其中w代表待排序数据的值域大小,即这些数在哪个区间里面,比如(0,最大值),其中最大值不要超过上面的W即100010,而且输入不能有负数
  • 原理

    • 对nums进行第1次循环(正向),把当前值当成索引,每出现一次,就让记录数组cnt对应位置的值加1
    • 对记录数组cnt进行 前缀和 叠加操作,目的是得出他们在新数组a中应该呆的位置
    • 对nums进行第2次循环(反向),并在记录数组cnt中找到其在新数组a中的位置关系,并放入a中
    • 把a交换到nums上面即可
    • 只能用于正数,所以一定要把生成负数的部分注释掉
#include <iostream>
#include <vector>
#include<bits/stdc++.h>
using namespace std;

void countingSort(vector<int>& nums) {
    const int W = 100010;
    int cnt[W];
    memset(cnt, 0, sizeof(cnt));
    int len = nums.size();
    vector<int> a(len);
    for(int i = 0; i < len; ++i) ++cnt[nums[i]];
    for(int w = 1; w < W; ++w) cnt[w] += cnt[w - 1];
    for(int i = len - 1; i >= 0; --i) a[--cnt[nums[i]]] = nums[i];
    nums.swap(a);
};

void shuffle(vector<int>& arr) {
    int n = arr.size();
    srand(time(NULL));
    while (n--) {
        const int random = rand() % arr.size();
        swap(arr[n], arr[random]);
    }
}

int main() {
    vector<int> testArr = {5, 7, 3, 4, 2, 6, 1};
    shuffle(testArr);
    countingSort(testArr);
    for(auto e: testArr) cout<<e<<endl;
    return 0;
}