数据结构与算法 —— O(n)排序算法(计数排序)(c++)

最快的两种排序:计数(空间换时间),桶排序
一种以最大空间换时间的算法,但是我们必须知道数字取值范围
计数排序时间复杂度O(n) 空间复杂度S(n)计数排序:就是使用的是vector代替map原理,比如我取值范围是100,那么我就建立一个vector大小为100
使用下标代替数字,值代表出现次数。这样只需要遍历一次就可以排序完成。
但是我们必须知道数字取值范围,然后创建这么大的一个数组
//时间复杂度为O(n) + O(k) k为传入数的范围,因为第二个遍历要遍历k次。空间复杂度为S(K) + S(N)为结果数组大小
稳定

#include <iostream>
#include <vector>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>

using namespace std;

vector<int> countSort(vector<int>& nums) {
    
    
    int rangeSize = nums.size();
    vector<int> counter(rangeSize, 0);//创建数组存储每个数出现的数量
    //遍历一遍数组,放入vector中,下标作为nums中的数,值作为出现数量
    //放入vector后我们就已经将数组排好序了,因为下标是排序放置
    for (int n : nums) {
    
    
        counter[n]++;
    }
    //将存储数量的数组遍历,并存入一个结果数组返回
    vector<int> res;
    for (int i = 0; i < rangeSize; i++) {
    
    
        //如果该数出现多次,则需要遍历存放
        while(counter[i] > 0) {
    
    
            res.push_back(i);
            counter[i]--;
        }
    }
    return res;
}



int main()
{
    
    
    int N = 1000;  
    srand(time(NULL));  //生成随机数种子
    //放到vector中
    vector<int> nums(N);
    for (int i = 0; i < N; ++i) {
    
    
        nums[i] = 1 + (rand() % N);
    }
    //开始计时
    double start, finish; 
    start = (double)clock();


    //200000
    //mergeSortMain(nums); //57ms
    //quickSort(nums, 0, N-1);//32ms 
    nums = countSort(nums); // 5ms


    finish = (double)clock();
    //打印
    // for (auto item : nums) {
    
    
    //     cout << item << ",";
    // }
    cout << endl;
    cout << (finish) - start << " ms" << endl;
}

猜你喜欢

转载自blog.csdn.net/chongbin007/article/details/114556532
今日推荐