大顶堆的构建,插入、删除与遍历(C语言)

#include<stdio.h>
#include<stdlib.h>
struct MaxHeap{
    int *data;
    int size;
    int maxsize;
};
struct MaxHeap *createMaxH(int maxSize){
    struct MaxHeap *H;
    H=(struct MaxHeap *)malloc(sizeof(struct MaxHeap)*maxSize);
    H->data=(int *)malloc(sizeof(int)*maxSize);
    H->size=0;
    H->maxsize=maxSize;
    return H;
}
int isEmpty(struct MaxHeap *H){
    return H->size==0;
}
int isFull(struct MaxHeap *H){
    return H->size==H->maxsize;
}
int findMax(struct MaxHeap *H){
    if(isEmpty(H)){
        printf("Heap is empty.\n");
        exit(-1);
    }
    return H->data[0];
}
void insert(struct MaxHeap *H,int num){/*插入核心代码*/
    if(isFull(H)){
        printf("Heap is full.\n");
        return;
    }
    int i=H->size;/*首先暂时将待插入值的位置设为接在数组最末尾*/
    while(i!=0&&H->data[(i-1)/2]<num){/*进行迭代,如果该节点不是数组首节点,那么就存在该节点的父节点,如果再满足父节点小于待插入值,那么根据大顶堆的特性父节点就要下沉,待插入位置上浮*/
        H->data[i]=H->data[(i-1)/2];/*父节点下沉*/
        i=(i-1)/2;/*更新i的值,即待插入位置上浮*/
    }
    H->data[i]=num;/*循环结束后i的位置就是待插入位置*/
    H->size++;/*插入后数组节点个数加一*/
}
int deleteMax(struct MaxHeap *H){/*最大值出堆的核心代码*/
    if(isEmpty(H)){
        printf("Heap is empty.\n");
        exit(-1);
    }
    int max,last,i,child;
    max=H->data[0];/*找到即将出堆的最大节点,即数组第一个*/
    last=H->data[H->size-1];/*找到数组最后一个节点,删除最大节点后,将该节点往前插*/
    H->size--;/*由于删除了最大节点,数组节点数减一*/
    for(i=0;2*i+1<H->size;i=child){/*将待插入节点位置暂设为第一个,如果待插入位置存在左子节点,进行迭代*/
        child=2*i+1;/*记录左子节点*/
        if(child<H->size-1&&H->data[child]<H->data[child+1]){
            child++;/*如果存在右子节点且左子节点小于右子节点,将child更新为右子节点*/
        }
        if(last<H->data[child]){/*如果待插入值,即数组最后一个节点,小于child的值,就将child上浮(因为大顶堆需要大的值在上面)*/
            H->data[i]=H->data[child];
        }else{
            break;/*待插入值已经比左右子节点大了,即找到了待插入位置,跳出循环*/
        }
    }
    H->data[i]=last;/*将待插入位置用last填上*/
    return max;/*返回出堆的最大值*/
}
void preOrder(struct MaxHeap *H,int i){
    if(i<H->size){
        printf("%4d",H->data[i]);
        preOrder(H,2*i+1);
        preOrder(H,2*i+2);
    }
}
void inOrder(struct MaxHeap *H,int i){
    if(i<H->size){
        inOrder(H,2*i+1);
        printf("%4d",H->data[i]);
        inOrder(H,2*i+2);
    }
}
void postOrder(struct MaxHeap *H,int i){
    if(i<H->size){
        postOrder(H,2*i+1);
        postOrder(H,2*i+2);
        printf("%4d",H->data[i]);
    }
}
int main(){
    struct MaxHeap *H;
    H=createMaxH(20);
    for(int i=0;i<10;i++){
        insert(H,i+1);
    }
    printf("堆构建完成后堆中最大值为:%3d",findMax(H));
    printf("\n先序遍历:");
    preOrder(H,0);
    printf("\n中序遍历:");
    inOrder(H,0);
    printf("\n后序遍历:");
    postOrder(H,0);
    deleteMax(H);
    printf("\n将最大值出堆后堆中最大值为:%3d",findMax(H));
    printf("\n先序遍历:");
    preOrder(H,0);
    printf("\n中序遍历:");
    inOrder(H,0);
    printf("\n后序遍历:");
    postOrder(H,0);
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值