1.15 Blog de aprendizaje

Practiqué unas cuantas pilas de preguntas hoy, y resumiré dos de ellas a continuación.
Las ideas básicas de estos dos temas son las mismas, una es la pila de raíces grande y la otra es la pila de raíces pequeña.

Problema de montón raíz grande: el elemento Kth más grande
Inserte la descripción de la imagen aquí
en la matriz. De hecho, este problema se puede resolver con otros métodos de clasificación básicos y comunes, pero aquí, se elige un método basado en la clasificación de montón.

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

Problema de pila de raíces pequeña: el número más pequeño de k en
Inserte la descripción de la imagen aquí
realidad no es difícil de usar métodos convencionales para los dos problemas. Una vez que comprenda el problema, encontrará que, de hecho, la naturaleza es la misma y se puede realizar mediante el método basado en la clasificación del montón. Este problema es el mismo que el anterior. Es básicamente el mismo, excepto que aquí se utilizan pequeñas pilas de raíces.

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

Estos dos temas son simples en sí mismos, y el programa es simple y fácil de entender, lo que puede ayudar a todos a comprender el proceso de ajuste de la clasificación de pilas y sus ideas básicas.

Supongo que te gusta

Origin blog.csdn.net/weixin_47529865/article/details/112679440
Recomendado
Clasificación