排序必刷题
题解
1.数组中的第K个最大元素
题目链接:215.数组中的第K个最大元素
题目大意:
解析:先排序后直接输出倒数第k个数。
快排解法
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
//基本思想:排序,然后找倒数第k个数
//排序方法:快排
//快排的基本想法:首先从high所指位置,向前搜索到第一个小于pivot的数互换位置,然后从low位置向 //后搜索,找到第一个比pivot大的数,互换位置。(无论是向前或者向后搜索,找到合适的后low和high)
//都不改变(即:不用low++或者high--)
//循环,直到low>=high
//结束
Qsort(nums,0,nums.size()-1);
return nums[nums.size()-k];
}
void Qsort(vector<int>& nums,int low,int high){
if(low < high){
int temp=partSort(nums,low,high);
Qsort(nums,low,temp-1);
Qsort(nums,temp+1,high);
}
}
int partSort(vector<int>& nums,int low,int high){ //起始位置low,high
int pivot=nums[low]; //将每一部分的第一个元素视作中心点
int temp=low; //保存pivot点的位置
while(low<high){
while(low<high){
if(nums[high]<pivot){
nums[temp]=nums[high];
temp=high;
nums[temp]=pivot;
break;
}
high--;
}
while(low<high){
if(nums[low]>pivot){
nums[temp]=nums[low];
temp=low;
nums[temp]=pivot;
break;
}
low++;
}
}
return temp;
}
};
堆排解法
堆排序基本步骤:
1.构建最大(最小)堆;
2.逐一取出堆顶元素(为最大或者最小),然后将最后一个元素放到树顶,重新构造堆;
3.循环上述过程,直到所有元素取出,取出的数为从大(小)的顺序。
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
//先排序,后直接输出倒数第k个数
//排序方法:堆排
int heapsize=nums.size();
BulidMaxHeap(nums,heapsize);
int heaptop;
//开始排序,每次都删除堆顶元素,然后将最后一个叶子节点补到堆顶中,再次建立堆
for (int i = nums.size() - 1; i >= nums.size() - k + 1; --i) {
swap(nums[0], nums[i]);
--heapsize;
MaxHeap(nums, 0, heapsize);
}
return nums[0];
}
void MaxHeap(vector<int> &nums,int i,int heapsize){
int l=2*i+1; //节点i的左子节点的下标
int r=2*i+2; //节点i的右子节点的下标
int largest=i;
//建立一个大顶堆
if(l<heapsize && nums[l] > nums[largest]){
largest=l;
}
if(r<heapsize && nums[r]>nums[largest]){
largest=r;
}
if(largest!=i) //将较大的数放在根节点处时,其相应的子树可能会发生改变,利用递归操作子树
{
int temp=nums[i];
nums[i]=nums[largest];
nums[largest]=temp;
MaxHeap(nums,largest,heapsize);
}
}
void BulidMaxHeap(vector<int> &nums,int heapsize)
{
for(int i=heapsize/2;i>=0;i--) //heapsize/2为最后一个非叶子节
{
MaxHeap(nums,i,heapsize);
}
}
};