各种排序算法

快速排序:

 void QuickSort(vector<int>& nums, int lo, int hi){
        if(lo < hi){
            int p = partition(nums,lo,hi);
            QuickSort(nums,lo,p-1);
            QuickSort(nums,p+1,hi);
        }
    }
    int partition(vector<int>& nums, int lo, int hi){
        int pivot = nums[lo];
        while(lo < hi){
            while( lo < hi && nums[hi] > pivot) --hi;// nums[hi] < pivot 则从大到小排序
            nums[lo] = nums[hi];//小的放左边
            while( lo <hi && nums[lo] <= pivot) ++lo;
            nums[hi] = nums[lo];//大的放右边
        }
        nums[lo] = pivot;//pivot放中间
        return lo;
    }

引出快速选择:选取第k大的元素:

int findKthLargest(vector<int>& nums, int k) {
        srand(time(NULL));
        return QuickChoose(nums, 0, nums.size() - 1, k);
    }
    int QuickChoose(vector<int>& nums, int lo, int hi,int k){
        if(lo <= hi){
            int p = partition(nums,lo,hi);
            if(p == k - 1) return nums[p];//p左边元素都比p大
            else if( p > k-1) return QuickChoose(nums, lo, p-1, k);
            return QuickChoose(nums, p+1, hi,k);
        }
        return -1;
    }
    int partition(vector<int>& nums, int lo, int hi){
        int t = rand()%(hi - lo +1)+lo;//加入随机
        swap(nums[lo],nums[t]);
        int pivot = nums[lo];
        while(lo < hi){
            while( lo < hi && nums[hi] < pivot) --hi;
            nums[lo] = nums[hi];//大的放左边
            while( lo <hi && nums[lo] >= pivot) ++lo;
            nums[hi] = nums[lo];//小的放右边
        }
        nums[lo] = pivot;//pivot放中间
        return lo;
    }

插入排序

void InsertSort(vector<int>& nums){
        int n = nums.size();
        for(int i = 1; i< n; i++){
            int t = nums[i];//先取出nums[i]
            int j = i;
            while( j > 0 && nums[j-1] > t){
                nums[j] = nums[j-1];
                j--;
            }
            //找到正确的位置
            nums[j] = t;
        }
    }

shell排序

 void ShellSort(vector<int>& nums){
        int n = nums.size();
        for(int k = n/2; k >= 1; k/=2){
            // InsertSort
            for(int i = k; i < n; i++){
                int t = nums[i];
                int j = i;
                while(j - k >= 0 && nums[j-k] > t){
                    nums[j] = nums[j-k];
                    j -= k;
                }
                nums[j] = t;
            }
        }
    }

归并排序:没有做空间优化

 void merge(vector<int>& nums,int lo, int hi){
        int mid = (lo+hi)/2;
        vector<int> temp;
        int i = lo, j = mid+1;
        while(i <= mid && j <= hi){
            if(nums[i] <= nums[j]) temp.push_back(nums[i++]);
            else temp.push_back(nums[j++]);
        }
        while(i <= mid) temp.push_back(nums[i++]);
        while(j <= hi) temp.push_back(nums[j++]);
        for(int i = lo; i <= hi; i++)
            nums[i] = temp[i-lo];
    }
    void MergeSort(vector<int>& nums, int lo, int hi){
        if(lo >= hi) return;
        int mid = (lo + hi)/2;
        MergeSort(nums,lo,mid);
        MergeSort(nums,mid+1,hi);
        merge(nums,lo,hi);
    }

空间优化:

void merge(vector<int>& nums,vector<int>& temp,int lo, int hi){
        int mid = (lo+hi)/2;
        int i = lo, j = mid+1;
        int t = lo;
        while(i <= mid && j <= hi){
            if(nums[i] <= nums[j]) temp[t++] = nums[i++];
            else temp[t++] = nums[j++];
        }
        while(i <= mid) temp[t++] = nums[i++];
        while(j <= hi) temp[t++] = nums[j++];
        for(int i = lo; i <= hi; i++)
            nums[i] = temp[i];
    }
    void MSort(vector<int>& nums,vector<int>& temp, int lo, int hi){
        if(lo >= hi) return;
        int mid = (lo + hi)/2;
        MSort(nums,temp,lo,mid);
        MSort(nums,temp,mid+1,hi);
        merge(nums,temp,lo,hi);
    }
    void MergeSort(vector<int>& nums){
        vector<int> temp(nums.size());
        MSort(nums,temp,0,nums.size() - 1);
        temp.clear();
    }

堆排序

void percdown(vector<int>& nums, int n, int index){
        int t = nums[index];// 先取出index处的值
        int pa = index, chi;
        while(pa*2+1 < n){
            chi = pa*2 + 1;
            if(chi != n-1 && nums[chi] <nums[chi+1])
                chi++;
            if(t >= nums[chi]) break;//找到了正确的位置
            nums[pa] = nums[chi];
            pa = chi;//
        }
        nums[pa] = t;//把t放在正确的位置上
    }
    void HeapSort(vector<int>& nums){
        int n = nums.size();
        //建堆
        for(int i = n/2-1; i >= 0; i--)
            percdown(nums,n,i);
        for(int i = n-1; i >= 1; i--){
            //把最大的放在最后
            swap(nums[0],nums[i]);
            //调整交换后这个值的位置
            percdown(nums,i,0);
        }
    }

 基数排序

参考:

https://www.cnblogs.com/skywang12345/p/3603669.html

https://www.cxyxiaowu.com/2106.html

https://www.cnblogs.com/onepixel/p/7674659.html

void RadixSort(vector<int>& nums){
        int n = nums.size();
        int max = INT_MIN;
        //找出长度最长的数组
        for(auto x:nums) if(abs(x) > max) max = x;
        //位数从最小位开始
        int exp = 1;
        //从-9到9共19个桶
        int buckets[19] = {0};
        vector<int> t(n);
        while(max/exp){
            memset(buckets,0,sizeof buckets);
            // 将数据出现的次数存储在buckets[]中
            for(int i = 0; i < n; i++)
                buckets[nums[i]/exp%10 + 9]++;
            // 更改buckets[i]。目的是让更改后的buckets[i]的值,是该数据在output[]中的位置。
            for(int i = 1; i < 19; i++)
                buckets[i] += buckets[i-1];
            // 将数据存储到临时数组output[]中,从后往前遍历是为了数据的稳定性
            for(int i = n-1; i >= 0; i--)
                t[--buckets[nums[i]/exp%10+9]] = nums[i];
            //排序好的数组赋值给nums
            nums = t;
            exp*= 10;           
        }
    }