堆的操作 及对应题目

一、堆的基本操作

以大根堆为例

包括——初始化堆、调整堆、插入元素和删除元素
对应时间复杂度为O(n)(自底向上建堆),O(logn),O(logn),O(logn)

插入操作:先将新元素添加到堆的末尾;如果它比父节点更大则交换,直到更小。
删除操作是:把堆顶和堆底元素交换,然后再调整[堆顶,堆底前一个元素间]所有元素为一个新的堆

1.1 堆排序:

  • 首先将无序序列构造成大根堆——堆顶元素为最大值
  • 输出堆顶元素后,将剩余元素调整为新的堆,再输出堆顶。

1.2 “找数组中的第K个最大元素”

对于下标从1开始的数组这样是对的:

class Solution {
public:
    //学会用桶排 和 基于快排的方法来做

    //使[start,end]成为大根堆
    void HeapAdjust(vector<int>& nums,int start,int end){
        int temp = nums[start];//待会有可能交换
        for(int i=2*start;i<=end;i*=2){
            if(i < end && nums[i]<nums[i+1])
                i++;
            if(nums[i] <= temp)break;//根节点大于子节点,不必调节
            //否则
            nums[start] = nums[i];
            start = i;
        }
        nums[start] = temp;
    }

    int findKthLargest(vector<int>& nums, int k) {
        int n = nums.size();
        //自下而上建堆法
        for(int i = n/2-1; i>=0; i--){
            HeapAdjust(nums,i,n-1);//[n-1]是最后一个节点
        }
        //做 k−1 次删除操作后堆顶元素就是我们要找的答案
        for(int i = n-1; i>n-k ; i--){//n-1 - (k-1) = n-k
            swap(nums[0],nums[i]);//堆顶和当前未排序子序列最后一记录交换
            HeapAdjust(nums,0,i-1);//对[0,i-1]调整为大根堆
        }
        return nums[0];
    }
};

但对于下标从0开始的,应该修改:

        //自下而上建堆法
        for(int i = n/2-1; i>=0; i--){
            HeapAdjust(nums,i,n-1);//[n-1]是最后一个节点
        }
//使[start,end]成为大根堆
    void HeapAdjust(vector<int>& nums,int start,int end){
	int temp = nums[start];//待会有可能交换
	for(int i=2*start+1;i<=end;i=2*i+1){

优先队列实现堆

参考自己的这篇文章(含题目“前K个高频元素”)
https://www.cnblogs.com/neromegumi/p/18515471

posted @   NeroMegumi  阅读(5)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
点击右上角即可分享
微信分享提示