快速排序、堆排序等各类排序算法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