1.15 Learning Blog

I practiced a few piles of questions today, and I will summarize two of them below.
The basic ideas of these two topics are the same, one is the big root pile and the other is the small root pile.

Big root heap problem: the Kth largest element
Insert picture description here
in the array. In fact, this problem can be solved by other basic and common sorting methods, but here, it happens to choose a method based on heap sorting.

我们也可以使用堆排序来解决这个问题——建立一个大根堆。
做 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次后最大的
}

Small root pile problem: The smallest number of k is
Insert picture description here
actually not difficult to use conventional methods for the two problems. After understanding the problem, you will find that in fact, the nature is the same, and both can be implemented by the method based on heap sorting. This problem is the same as the previous one It's basically the same, except that small root piles are used here.

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;
}

These two topics are simple in themselves, and the program is simple and easy to understand, which can help everyone understand the adjustment process of heap sorting and its basic ideas.

Guess you like

Origin blog.csdn.net/weixin_47529865/article/details/112679440