计数排序算法——C++

本文详细介绍了计数排序算法的基本实现和优化过程,优化后的计数排序通过累加非零元素来确定排序位置,从而保持稳定性。文章包括具体实现步骤、完整代码示例以及优化版的思路和区别。
摘要由CSDN通过智能技术生成

计数排序是时间复杂度为 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
计数排序是一种非比较型整数排序算法,它适用于待排序数据范围较小的情况,通常用于对一定范围内整数的排序。在C++中实现计数排序的基本步骤如下: 1. **获取输入数组的最大值**:遍历数组找出最大值`max_val`,以便确定桶的数量。 2. **创建计数数组**:初始化一个大小为`max_val + 1`的计数数组`count[]`,所有元素初始化为0。这个数组将用于存储每个元素在原始数组中出现的次数。 3. **统计每个元素出现次数**:遍历输入数组,对于每一个元素`val`,将`count[val]`加一。 4. **累计计数**:从数组末尾开始,将每个位置的计数值累加到前一个位置,模拟每个元素实际的位置。 5. **构建排序后的数组**:从最小值开始,按照计数数组`count[]`的顺序,复制元素到新的数组中,并更新原数组的对应位置。 6. **返回结果**:最后得到的结果数组就是已排序的序列。 以下是简单的C++代码示例: ```cpp #include <iostream> using namespace std; void countingSort(int arr[], int n) { // 步骤1 & 2 int max_val = *max_element(arr, arr+n); int count[max_val+1] = {0}; // 步骤3 for (int i = 0; i < n; ++i) { count[arr[i]]++; } // 步骤4 for (int i = 1; i <= max_val; ++i) { count[i] += count[i - 1]; } // 步骤5 & 6 int output[n]; for (int i = n - 1; i >= 0; --i) { output[count[arr[i]] - 1] = arr[i]; count[arr[i]]--; } for (int i = 0; i < n; ++i) { arr[i] = output[i]; } } int main() { int arr[] = {4, 2, 2, 8, 3, 3, 1}; int n = sizeof(arr) / sizeof(arr[0]); countingSort(arr, n); cout << "Sorted array is: "; for (int i = 0; i < n; ++i) { cout << arr[i] << " "; } return 0; } ```
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

三公子Tjq

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

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

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

打赏作者

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

抵扣说明:

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

余额充值