用C实现堆的基本操作

本文介绍了一个堆数据结构的实现细节,包括头文件和源文件的内容。堆被定义为一种特殊的完全二叉树形式,其中每个父节点的键都小于或等于其子节点的键(最小堆),或者每个父节点的键都大于或等于其子节点的键(最大堆)。文中提供了创建堆、插入元素、调整堆、删除元素等关键操作的具体实现。
摘要由CSDN通过智能技术生成

头文件
Heap.h

#pragma once
#include<stdlib.h>
#include<stdio.h>
#include<assert.h>
#include<string.h>

typedef int Datatype;
typedef int(*Compare)(Datatype left, Datatype right); //函数指针

typedef struct Heap
{
    Datatype *_hp;
    int _capacity;
    int _size;
    Compare _com;
}Heap;

void swap(Datatype *left, Datatype *right);        //交换函数
void AdjustDown(Heap *pHp, int parrent);           //向下调整
void AdjustUp(Heap* pHp, int child);               //向上调整
void Create(Heap *pHp, Datatype array[], int size, Compare com);    //创建堆
void InitHeap(Heap* pHp, Compare com);                              //初始化堆
void Insert(Heap* pHp, Datatype data);                              //插入元素
int EmptyHeap(Heap *php);                                           //判断是否为空堆
void Remove(Heap* pHp);                                             //删除堆中元素
void CheckCapacity(Heap *php);                                      //增容
int SizeHeap(Heap* pHp);                                            //堆大小
Datatype HeapTop(Heap *php);                                        //堆顶元素

int Less(Datatype left, Datatype right);                            
int Greater(Datatype left, Datatype right);

源文件
Heap.c

#include "Heap.h"

void swap(Datatype *left, Datatype *right)
{
    int tmp = *left;
    *left = *right;
    *right = tmp;
}

void InitHeap(Heap* pHp, Compare com)
{
    pHp->_hp = (Datatype*)malloc(sizeof(Datatype) * 3);
    if (NULL == pHp)
        return;
    pHp->_capacity = 3;
    pHp->_size = 0;
    pHp->_com = com;
}

void AdjustDown(Heap *pHp, int parrent)//小堆
{
    if (NULL == pHp)
    {
        return;
    }
    int child = parrent * 2 + 1;
    while (child < pHp->_size)
    {
        if ((child + 1 < pHp->_size) && (pHp->_hp[child] > pHp->_hp[child + 1]))
        {
            child = child + 1;
        }
        if (pHp->_hp[child] < pHp->_hp[parrent])
        {
            swap(&pHp->_hp[child], &pHp->_hp[parrent]);
            parrent = child;
            child = parrent * 2 + 1;
        }
        else
            return;
    }
}

void AdjustUp(Heap* pHp, int child)//大堆
{
    if (NULL == pHp)
    {
        return;
    }
    int parrent = (child - 1) >> 2;
    if (pHp->_hp[child] > pHp->_hp[parrent])
    {
        swap(&pHp->_hp[child], &pHp->_hp[parrent]);
        child = parrent;
        parrent = (child - 1) >> 1;
    }
    else
        return;
}

void Create(Heap *pHp, Datatype array[], int size, Compare com)
{
    int i = 0;
    int root = 0;
    pHp->_hp = (Datatype*)malloc(sizeof(Datatype)*(size + 3));
    assert(pHp);
    pHp->_capacity = size + 3;
    for (i = 0; i < size; ++i)
    {
        pHp->_hp[i] = array[i];
        pHp->_size++;
    }
    pHp->_size = size;
    pHp->_com = com;
    root = (size - 2) >> 1;
    for (; root >= 0; root--)
    {
        AdjustDown(pHp, root);
    }
}

void CheckCapacity(Heap *php)//lll
{
    if (php->_size >= php->_capacity)
    {
        int pnewcapacity = php->_capacity * 2;
        Datatype *pnew = (Datatype *)malloc(sizeof((Datatype *)pnewcapacity));
        assert(pnew);
        memcpy(pnew, php->_hp, php->_size * sizeof(Datatype));
        free(php->_hp);
        php->_hp = pnew;
        php->_capacity = pnewcapacity;
    }
}

void Insert(Heap* pHp, Datatype data)
{
    if (NULL == pHp)
    {
        return;
    }
    CheckCapacity(pHp);
    pHp->_hp[++pHp->_size] = data;
    if (pHp->_size > 1)
    {
        AdjustUp(pHp, pHp->_size - 1);
    }
}

int EmptyHeap(Heap *php)
{
    assert(php);
    return php->_size == 0;
}

void Remove(Heap* pHp)
{
    if (NULL == pHp)
        return;
    if (EmptyHeap(pHp))
        return;
    swap(&pHp->_hp[0], &pHp->_hp[pHp->_size - 1]);
    pHp->_size--;
    AdjustDown(pHp, 0);
}

int SizeHeap(Heap* pHp) 
{
    return pHp->_size;
}

Datatype HeapTop(Heap *php)
{
    assert(php);
    if (EmptyHeap(&php))
    {
        return -1;
    }
    return php->_hp[0];
}

int Less(Datatype left, Datatype right)
{
    return left < right;
}

int Greater(Datatype left, Datatype right)
{
    return left > right;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值