计数排序是时间复杂度为 O(n)的算法,空间复杂度为O(n);算法思想跟散列表哈希hash有些类似,主要是利用一段有序数组计算对应元素的下表个数,然后依次输出有数组元素进行排列。基本计数排序是不稳定算法,但是优化后计数排序是稳定算法。本文主要讲解基本计数排序和优化后计数排序。
使用条件:数组必须是整数或者能全部映射为整数,数组所有元素必须在有限较集中范围;
一、具体实现步骤
1.计算原始数组的最大值max和最小值min范围,然后创建一个长度为max--min+1的排序数组sortArr(max--min+1);
该数组sortArr目的是计算每个原始数组每个元素的个数
auto minmax = std::minmax_element(nums.begin(), nums.end()); // minmax_element(begin,end)可以输入迭代器而minmax(l,r)不能输入迭代器
int min = *minmax.first;
int max = *minmax.second;
int index = 0;
vector<int> sortArr(max - min + 1, 0); // 创建一段数组用来存储每个元素个数
vector<int> result(nums.size()); // 创建一段数组用来存储每个元素个数
2.遍历原始数组,将原始数组的值作为排序数组sortArr的下标进行计数;
此时原始数组所有元素个数已经计算出来并顺序存放;注意:存储下标的时候需要减去最小值,将原始数组缩放到排序数组范围内。
for (const auto& it : nums) // 遍历原始数组,计算所有元素个数;sortArr下标是元素,值是该元素个数
{
sortArr[it - min]++;
}
3.遍历排序数组sortArr,将所有非零的值取出下标作为输出数组元素;
这里注意取出下标的时候需要加上最小值,因为前面存入的时候减了最小值。
for (int i = 0; i < sortArr.size(); ++i) // 遍历有序数组,值为非零则取出排列
{
while (sortArr[i])
{
result[index] = i + min;
++index;
--sortArr[i];
}
}
4.最后返回结果数组或者赋值给原来数组
nums = result;
二、完整代码示例
Sorts.h
#pragma once
#include <iostream>
#include <vector>
using namespace std;
struct Sorts {
void count(vector<int>& nums);
void print(vector<int>& nums);
};
Sorts.cpp
#include "Sorts.h"
#include <algorithm>
void Sorts::count(vector<int>& nums)
{
if (nums.si