堆排序实现

  • 大顶堆:当前节点值大于其左右节点,可用来计算top K小的元素
  • 小顶堆:当前节点值小于其左右节点,可用来计算top K大的元素
    #include <bits/stdc++.h>
    
    
    using namespace std;
    /*
    堆排序算法实现:
    大顶堆的建立,以及堆的维护
    当前节点大于其左右节点,每次筛选出最大的节点,可以维持最小的K个元素
    算法时间复杂度,O(nlogn)
    */
    
    
    void HeapAdjust(int a[], int len, int index){
        //对a[index]--a[len]元素进行排序,使得a[index]为最大元素
        int left = 2 * index;
        int right = 2 * index + 1;
        int max_index = index;
        if(left <= len && a[left] > a[max_index]) max_index = left;
        if(right <= len && a[right] > a[max_index]) max_index = right;
        if(max_index != index){//最大元素所在位置有更新
            swap(a[max_index], a[index]); //元素交换位置
            HeapAdjust(a, len, max_index);
        }
    }
    
    void HeapSort(int a[], int len){
        for(int i = len/2; i > 0; i--) HeapAdjust(a, len, i);//对每一个非叶子节点从后往前进行调整,生成初始大顶堆
        for(int i = len -1; i >= 1; i--){
            swap(a[i+1], a[1]); //将当前最大元素放到数组末尾
            HeapAdjust(a, i, 1); //对未完成部分继续进行堆排序
        }
    }
    
    int main(){
        int a[9] = {0, 49, 97, 65, 49, 76, 13, 27, 38};
        HeapSort(a, 8);
        for(int i = 1; i <= 8; i++)
            cout<<a[i]<<endl;
    }

    215. 数组中的第K个最大元素

 

给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。

请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。

示例 1:

输入: [3,2,1,5,6,4] 和 k = 2
输出: 5
示例 2:

输入: [3,2,3,1,2,4,5,5,6] 和 k = 4
输出: 4

 

#include "bits/stdc++.h"

using namespace std;

class Solution {
private:
    int val;
public:
    int Partition(vector<int>& nums, int l, int h){
        //对nums[l...h]元素进行筛选,将nums[l]放置到合适的位置
        int temp = nums[l];
        int low = l, high = h;
        while(low < high){
            while(low < high && nums[high] > temp){
                //从右一直往左扫描,直到不满足条件
                high -= 1;
            }
            swap(nums[low], nums[high]);
            while(low < high && nums[low] <= temp){
                //从左一直往右扫描,直到不满足条件
                low += 1;
            }
            swap(nums[low], nums[high]);
        }
        nums[low] = temp;
        return low;
    }
    void quick_sort(vector<int> nums, int l, int h, int k){
        if(l <= h){
            int p = Partition(nums, l, h);
            if(p == k){
                val = nums[p];
                return;
            }else if(p < k){
                quick_sort(nums, p+1, h, k);
            }else if(p > k){
                quick_sort(nums, l, p-1, k);
            }
        }else{
            return;
        }
        
    }
    int findKthLargest(vector<int>& nums, int k) {
        //使用快排,快排返回位置刚好为k,返回即可
        int l = 0, h = nums.size()-1;
        int index = nums.size() - k;
        quick_sort(nums, l, h, index);
        return val;
    }
    int findKthLargest_heap(vector<int>& nums, int k) {
        //使用小顶堆(大小为k)
        vector<int>::const_iterator first1 = nums.begin();
        vector<int>::const_iterator last1  = nums.begin() + k;
        vector<int> vec(first1, last1);
        for(int i = (k-1) / 2; i >= 0; i--){
            Heapadjust(vec, k, i);
        }
        for(int i = k; i < nums.size(); i++){
            if(nums[i] > vec[0])//大于堆顶元素,替换即可
            {
                vec[0] = nums[i];
                Heapadjust(vec, k, 0);
            }
        }
        return vec[0];
    }
    void Heapadjust(vector<int>& nums, int len, int index){
        //对下标为index的元素进行调整
        int left_index = 2 * index, right_index = 2 * index + 1;
        int min_index = index;
        if(left_index < len && nums[left_index] <= nums[min_index]){
            min_index = left_index;
        }
        if(right_index < len && nums[right_index] <= nums[min_index]){
            min_index = right_index;
        }
        if(min_index != index){
            swap(nums[index], nums[min_index]);
            Heapadjust(nums, len, min_index);
        }
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值