c++ 十种基础排序方法的实现

选择排序、快速排序、希尔排序、堆排序不是稳定的排序算法,而冒泡排序、插入排序、归并排序、计数排序(注意倒着插入)、桶排序和基数排序是稳定的排序算法

在这里插入描述

  1. 冒泡、选择、插入、归并、希尔、堆排序都是基于比较的排序
    平均时间复杂度最低O(nlogn)

  2. 计数排序、桶排序、基数排序不是基于比较的排序
    使用空间换时间,某些时候,平均时间复杂度可以低于O(nlog)

class Solution {
public:
    vector<int> sortArray(vector<int>& nums) {
        // quicksort(nums,0,nums.size()-1);
        // build(nums,nums.size());
        // shellsort(nums,nums.size());
        // countsort(nums);
        // insertsort(nums);
        // selectsort(nums);
        // bucketsort(nums,100000);
        // mergesort(nums,0,nums.size()-1);
        // bubblesort(nums);
        radixsort(nums,10);
        return nums;
    }
    //插入排序 最好O(N), 稳定排序
    void insertsort(vector<int> & nums)
    {
        for(int i = 1;i < nums.size(); i ++) {
            int tmp = nums[i];
            int j = i-1;
            while(j >= 0 && nums[j] > tmp) {
                nums[j+1] = nums[j];
                j--;
            }
            nums[j+1] = tmp;
        }
    }
    //冒泡排序 稳定排序
    void bubblesort(vector<int>& nums) 
    {
        for(int i = 0;i < nums.size(); i ++) {
            for(int j = 1;j < nums.size() - i ; j ++) {
                if(nums[j-1] > nums[j]) swap(nums[j-1],nums[j]);
            }
        }
    }
    //选择排序, 不稳定排序
    void selectsort(vector<int> & nums) 
    {
        for(int i = 0;i < nums.size(); i ++) {
            int index = i;
            for(int j = i + 1;j < nums.size(); j ++) {
                if(nums[j] < nums[index]) index = j;
            }
            swap(nums[index],nums[i]);
        }
    }
	//归并排序 稳定排序
    void mergesort(vector<int> &nums,int l,int r) 
    {
        if(l >= r) return;
        int mid = l + (r-l) / 2;
        mergesort(nums,l, mid);
        mergesort(nums,mid+1,r);
        vector<int> tmp;
        int i = l,j = mid+1;
        while(i <= mid && j <= r) {
            if(nums[i] < nums[j]) 
                tmp.emplace_back(nums[i++]);
            else 
                tmp.emplace_back(nums[j++]);
        }
        while(i <= mid) tmp.emplace_back(nums[i++]);
        while(j <= r) tmp.emplace_back(nums[j++]);
        for(int i = 0;i < r-l+1;i ++) nums[i+l] = tmp[i];
    }
	//快速排序,不稳定排序,最坏的时候是O(N^2)
    void quicksort(vector<int>& nums,int l, int r) 
    {
        if(l >= r) return;
        int p = partition(nums,l,r);
        cout << endl;
        quicksort(nums,l,p-1);
        quicksort(nums,p+1,r);
    }
    int partition(vector<int>& nums, int l,int r) 
    {
        int val = nums[l];
        while(l < r) {
            while(l < r && nums[r] >= val) r --;
            nums[l] = nums[r];
            while(l < r && nums[l] <= val) l ++;
            nums[r] = nums[l];
        }
        nums[l] = val;
        return l;
    }
	// 堆排序,任何情况都是O(NlogN) 不稳定
    void adjust(vector<int> & nums,int index,int size)
    {
        int l = 2*index+1;
        int r = 2*index+2;
        int maxid = index;
        if(l <= size && nums[l] > nums[maxid]) maxid = l;
        if(r <= size && nums[r] > nums[maxid]) maxid = r;
        if(maxid == index) return;
        swap(nums[index],nums[maxid]);
        adjust(nums,maxid,size);
    }
    void build(vector<int>& nums,int size) 
    {
        for(int i = size / 2 ; ~i; -- i) {
            adjust(nums,i,size-1);
        }
        for(int i = size-1; i >= 1; -- i) {
            swap(nums[0],nums[i]);
            adjust(nums,0,i-1);
        }
    }
    //希尔排序,不稳定排序
    void shellsort(vector<int> &nums, int size) 
    {
        for(int l = size/2; l >= 1; l /= 2) {
            for(int i = l; i < size; i ++) {
                if(nums[i] < nums[i-l]) {
                    int j = i - l;
                    int tmp = nums[i];
                    while(j >= 0 && nums[j] > tmp) {
                        nums[j+l] = nums[j];
                        j -= l;
                    }
                    nums[j+l] = tmp;
                }
            }
        }
    }
    //计数排序 稳定排序
    void countsort(vector<int>&nums) {
        int maxv = *max_element(nums.begin(), nums.end());
        int minv = *min_element(nums.begin(), nums.end());
        vector<int> count(maxv - minv+1,0);
        for(auto num : nums) count[num-minv] ++;
        for(int i = 1;i <= maxv-minv;i ++) count[i] += count[i-1];
        vector<int> tmp(nums.begin(),nums.end());
        for(int i = tmp.size()-1;~i ;i --) { // 倒过来保持稳定
            int pos = count[tmp[i] - minv];
            nums[pos-1] = tmp[i];
            count[tmp[i] - minv] --;
        }
    }
    //桶排序 稳定排序
    void bucketsort(vector<int>& nums,int k)
    {
        int maxv = *max_element(nums.begin(), nums.end());
        int minv = *min_element(nums.begin(), nums.end());
        int range = (maxv - minv + k - 1) / k;
        range = max(range,1);
        int cnt = 0;
        vector<vector<int> > bucket(k+1,vector<int>(0));
        for(auto num : nums) {
            int id = (num - minv) / range;
            bucket[id].emplace_back(num);
        }
        for(int i = 0;i <= k; i ++) {
            sort(bucket[i].begin(),bucket[i].end());
            for(int j = 0;j < bucket[i].size(); j ++) nums[cnt++] = bucket[i][j];
        }
    }
	//基数排序 稳定排序
    void radixsort(vector<int>& nums,int base)
    {
        vector<vector<int>> bucket;
        int maxv = *max_element(nums.begin(),nums.end());
        int minv = *min_element(nums.begin(), nums.end());
        for(int i = 1; i <= maxv-minv; i = i * base) {
            bucket.assign(base,vector<int>(0));
            for(int j = 0;j < nums.size(); j ++) {
                int index = (nums[j] - minv) / i % base;
                bucket[index].emplace_back(nums[j]);
            }
            int cnt = 0;
            for(int j = 0;j < base;j ++) {
                for(int k = 0; k < bucket[j].size(); k ++) {
                    nums[cnt ++] = bucket[j][k];
                }
            }
        }
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值