快速排序、堆排序等各類排序算法C++代碼,topK問題

1、快速排序

快速排序,面試常常可能碰到的題,今天整理了一下,方便之後本身查看複習。原理能夠參見博客:快速排序的原理
我也是參考這個博客的,寫的挺好的。如下是c++代碼。c++

#include<bits/stdc++.h>
using namespace std;
//找到基準數下標
int getIndex(vector<int>& arr, int low, int high) {
   int temp = arr[low];
   while (low < high) {
   	while (arr[high] >= temp && high > low)
  	 high--;
   	arr[low] = arr[high];
   	while (arr[low] <= temp && high > low)
   	low++;
   	arr[high] = arr[low];
 }
 arr[low] = temp;
 return low;
}
void quickSort(vector<int>& arr, int low, int high) {
    if (low < high) {
    	int index = getIndex(arr, low, high);
    	quickSort(arr, low, index - 1);
       quickSort(arr, index + 1, high);
    }
}
//主函數測試一下
int main() {
    vector<int> arr = { 2,18,5,1,7,4,39,23 };
    quickSort(arr, 0, arr.size() - 1);
    for (int i = 0; i < arr.size(); i++)
    cout << arr[i]<<" ";
    cout << endl;
}

輸出結果:在這裏插入圖片描述
快速排序不適合對已基本有序的數據排序,空間複雜度最好是O(logn),最壞是O(n);時間複雜度最好是O(nlogn),最壞是O(n^2);web

若是要用快排找第K小的數,實現以下:面試

class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        int low=0,high=nums.size()-1;
        while(low<=high){
            int index=getIndex(nums,low,high);
            if(index==k-1) return nums[index];
            else if(index<k-1) low=index+1;
            else high=index;
        }
        return -1;
    }
    //找到基準數下標
    int getIndex(vector<int>& nums, int low, int high) {
    //加這個隨機速度會變快,防止數組元素已經基本有序
        int idx=rand()%(high-low+1)+low;
        swap(nums[idx],nums[high]);

        int temp = nums[low];
        while (low < high) {
        	//若是要改爲找第K大的數,把下面改爲nums[high]<=temp
            while (nums[high] >= temp && high > low)
            high--;
            nums[low] = nums[high];
            //若是要改爲找第K大的數,把下面改爲nums[low]>=temp
            while (nums[low] <= temp && high > low)
            low++;
            nums[high] = nums[low];
        }
        nums[low] = temp;
        return low;
    }
};

2、堆排序,top K

若是是找最小的K個值用大頂堆,先從待排序數組中取前K個建立堆,再將後面的數依次與堆頂數比較,小於堆頂則插入,並從新調整堆。若是是找最大的K個值則相反。下面以大頂堆爲例。數組

#include<bits/stdc++.h>
using namespace std;
void adjustMinHeap(vector<int>& nums,int root,int len){
    int lch=2*root+1;
    int rch=lch+1;
    int index=root;
    //調整最大堆
    if(lch<len && nums[lch]>nums[index]) index=lch;
    if(rch<len && nums[rch]>nums[index]) index=rch;
    if(index!=root){
        swap(nums[index],nums[root]);
        adjustMinHeap(nums,index,len);
    }
}
vector<int> TopKInHeap(vector<int>& nums,int k){
    vector<int> res(nums.begin(),nums.begin()+k);
    //用前k個數創建最大堆
    for(int i=k/2-1;i>=0;i--)
        adjustMinHeap(res,i,k);
    for(int i=k;i<nums.size();i++){
        if(nums[i]<res[0]){//小於堆頂的數
            res[0]=nums[i];//插入最大堆並進行調整
            adjustMinHeap(res,0,k);
        }
    }
    return res;
}
int main() {
    int len, k;
    while (cin >> len >> k) {
        vector<int> nums(len);
        for (int i = 0; i < len; i++) cin >> nums[i];
        vector<int> res = TopKInHeap(nums, k);
        for (int i = 0; i < k; i++)
            cout << res[i] << ' ';
        cout << endl;
    }
}

3、冒泡排序

void BubbleSort(vector<int>& arr)
{
    int n = arr.size();
    for (int i = 0; i < n - 1; i++)
    {
        for (int j = 0; j < n - i - 1; j++)
        {
            if (arr[j] > arr[j + 1])
                swap(arr[j], arr[j + 1]);
        }
    }
}

4、桶排序

見力扣題目,利用桶排序解答svg