1.15学习博客

今天练习了几道堆的题目,下面总结两道。
这两道题目基本思想都一致,一个是大根堆,一个是小根堆。

大根堆题目:数组中的第K个最大元素
在这里插入图片描述
其实这道题目用其他基本常见的排序做法也可以解决,但是在这里,正好可以选择基于堆排序的方法来实现。

我们也可以使用堆排序来解决这个问题——建立一个大根堆。
做 k - 1 次删除操作后堆顶元素就是我们要找的答案。

部分代码如下:

void maxHeapify(int* a, int i, int heapSize) {
    int l = i * 2 + 1, r = i * 2 + 2, largest = i;//l是左孩子,r是右孩子
    if (l < heapSize && a[l] > a[largest]) {//左孩子存在且左孩子大于该结点值
        largest = l;
    }
    if (r < heapSize && a[r] > a[largest]) {//右孩子存在且右孩子大于该结点值
        largest = r;
    }
    if (largest != i) {//不相等则是调整过
        int t = a[i];
        a[i] = a[largest];
        a[largest] = t;
        maxHeapify(a, largest, heapSize);//对调整交换后的结点继续进行调整
    }
}
void buildMaxHeap(int* a, int heapSize) {
    for (int i = heapSize / 2; i >= 0; --i) {//i = heapSize / 2的意义是从倒着数第一个非叶子结点的结点开始建堆
        maxHeapify(a, i, heapSize);
    }
}
int findKthLargest(int* nums, int numsSize, int k) {
    int heapSize = numsSize;
    buildMaxHeap(nums, heapSize);//调整第一次
    for (int i = numsSize - 1; i >= numsSize - (k - 1); --i) {//求第k大,再调整k-1次
        int t = nums[0];
        nums[0] = nums[i];
        nums[i] = t;
        --heapSize;//去除首项,将末项放在首项,下面进行堆调整
        maxHeapify(nums, 0, heapSize);
    }
    return nums[0];//调整k-1次后最大的
}

小根堆题目:最小的k个数
在这里插入图片描述
其实两道题目用常规做法都不难,大家了解题目后会发现,其实性质一样,都可以用基于堆排序的方法来实现,这道题与上道题基本上一模一样,只是这里采用的是小根堆罢了。

void minHeapify(int* a, int i, int heapSize) {
    int l = i * 2 + 1, r = i * 2 + 2, largest = i;//l是左孩子,r是右孩子
    if (l < heapSize && a[l] < a[largest]) {//左孩子存在且左孩子小于该结点值
        largest = l;
    }
    if (r < heapSize && a[r] < a[largest]) {//右孩子存在且右孩子小于该结点值
        largest = r;
    }
    if (largest != i) {//不相等则是调整过
        int t = a[i];
        a[i] = a[largest];
        a[largest] = t;
        minHeapify(a, largest, heapSize);//对调整交换后的结点继续进行调整
    }
}
void buildMinHeap(int* a, int heapSize) {
    for (int i = heapSize / 2; i >= 0; --i) {//i = heapSize / 2的意义是从倒着数第一个非叶子结点的结点开始建堆
        minHeapify(a, i, heapSize);
    }
}
int* getLeastNumbers(int* arr, int arrSize, int k, int* returnSize){
 int heapSize = arrSize;
 int*mn=(int*)malloc(sizeof(int)*k);
 *returnSize=k;
 if(k==0)return mn;
 int p=0;
    buildMinHeap(arr, heapSize);
    mn[p++]=arr[0];//这里因为上面已经调整好一次,所以给mn加入一个值
    for (int i = arrSize - 1; i >= arrSize - (k - 1); --i) {//再调整k-1次
        int t = arr[0];
        arr[0] = arr[i];
        arr[i] = t;
        --heapSize;//去除首项,将末项放在首项,下面进行堆调整
        minHeapify(arr, 0, heapSize);
        mn[p++]=arr[0];//每调整好一次,为mn添一个值
    }
    return mn;
}

这两道题目本身题目简单,程序也简单易懂,可以帮助大家很好的理解堆排序的调整过程以及其基本思想。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值