C语言实现大顶堆

代码

#include <stdio.h>
#include <stdlib.h>
#define swap(a,b) {\
    __typeof(a) __tmp=a;\
    a=b, b=__tmp;\
}

typedef struct Heap { //大顶堆 完全二叉树
    int *data, size, len; //data线性
} Heap;

Heap *initHeap(int n) {
    Heap *h = (Heap *)malloc(sizeof(Heap));
    h->data = (int *)malloc(sizeof(int) * n);
    h->size = n, h->len = 0;
    return h;
}

void freeHeap(Heap *p) {
    if (!p) return ;
    free(p->data);
    free(p);
    return ;
}

int push(Heap *h, int val) { //尾部插入数据
    if (!h || h->size == h->len) return 0;
    h->data[h->len] = val;

    //调整插入位置
    int ind = h->len; //ind-当前节点 (ind-1)/2-父结点
    while (ind > 0 && h->data[ind] > h->data[(ind - 1) / 2]) {
        swap(h->data[ind], h->data[(ind - 1) / 2]);
        ind = (ind - 1) / 2;
    }

    ++h->len;
    return 1;
}

void downAdj(int *arr, int ind, int len) { //向下调整
    while (ind * 2 + 1 < len) { //左孩子存在
        int tmp = ind; //tmp记录父节点及左右孩子这3个节点最大的那个小标
        int l = ind * 2 + 1, r = ind * 2 + 2;  //l-左孩子 r-右孩子
        if (arr[l] > arr[tmp]) tmp = l;
        if (r < len && arr[r] > arr[tmp]) tmp = r;

        if (tmp == ind) break;
        swap(arr[tmp], arr[ind]);
        ind = tmp;
    }
    return ;
}

int isEmpty(Heap *h) {
    return !h || !h->len;
}

int pop(Heap *h) { //弹出大顶堆堆顶的元素
    int ret = h->data[0];
    h->data[0] = h->data[h->len - 1];
    --h->len;

    downAdj(h->data, 0, h->len);
    return ret;
}

int main() {
    return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 C 语言中构建小顶堆可以通过以下几个步骤完成: 1. 定义一个结构体来表示堆,包括堆的大小和堆的数组元素。 ``` typedef struct { int *arr; // 堆的数组元素 int size; // 堆的大小 } MinHeap; ``` 2. 实现交换函数 swap,用于交换堆中两个元素的位置。 ``` void swap(int *a, int *b) { int temp = *a; *a = *b; *b = temp; } ``` 3. 实现一个向下调整函数 siftDown,用于将一个元素向下调整到合适的位置,以维护堆的性质。 ``` void siftDown(int *arr, int start, int end) { int parent = start; int child = parent * 2 + 1; while (child <= end) { if (child + 1 <= end && arr[child] > arr[child + 1]) { child++; } if (arr[parent] <= arr[child]) { break; } else { swap(&arr[parent], &arr[child]); parent = child; child = parent * 2 + 1; } } } ``` 4. 实现一个建堆函数 buildHeap,用于将一个数组构建成小顶堆。 ``` void buildHeap(MinHeap *heap) { int i; for (i = heap->size / 2; i >= 0; i--) { siftDown(heap->arr, i, heap->size - 1); } } ``` 5. 实现一个弹出堆顶元素函数 pop,用于弹出堆顶元素,并重新调整堆。 ``` int pop(MinHeap *heap) { int top = heap->arr; heap->arr = heap->arr[heap->size - 1]; heap->size--; siftDown(heap->arr, 0, heap->size - 1); return top; } ``` 6. 最后,我们可以按照以下步骤来构建一个小顶堆: ``` int main() { int arr[] = {10, 20, 30, 40, 50, 60, 70}; int n = sizeof(arr) / sizeof(arr); MinHeap heap = {arr, n}; buildHeap(&heap); // 弹出堆顶元素 printf("%d ", pop(&heap)); return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值