C/C++最大堆代码

C代码

typedef struct heap{
    int capacity; // 堆的容量,即能容纳多少个有效的数据元素
    int size;     // 堆的当前数据量
    int* data;    // 指向堆中存放数据的地址,即数组的首元素
}maxHeap;

maxHeap* MaxHeapInit(int capacity)
{
    maxHeap* h = (maxHeap*)malloc(sizeof(maxHeap));          // 分配一个堆对象
    if(h!=NULL)
    {
        h->capacity = capacity;                              // 设置堆的容量
        h->size = 0;                                         // 当前堆的数据量为零
        h->data = (int*)malloc(sizeof(int)*(h->capacity+1)); // 根据堆的容量,为堆分配存放数据元素的空间
        if(h->data!=NULL)
        {
            h->data[0] = INT_MAX;                            // 堆中的首元素是作为辅助的,不用来存放有效的数据
        }
        else
        {
            free(h);
            return NULL;
        } 
    }
    return h;
}

// 插入使用空穴上浮
bool MaxHeapInsert(maxHeap* obj, int x)
{
    
    if(obj->size >= obj->capacity)         // 插入数据元素之前,需要判断堆中是否还有空余容量
        return false;
    else
    {
        int i = ++obj->size;               // i 表示空穴的当前位置!!!
        while(obj->data[i/2]<x)            // 空穴的父节点值小于空穴值(x 表示的是空穴值),那么空穴上浮
        {
            obj->data[i] = obj->data[i/2]; // 将空穴的父节点值保存到空穴的位置,然后空穴就可以上浮了
            i /= 2;                        // 空穴上浮
        }
        obj->data[i] = x;                  // 当跳出循环后,说明空穴的父节点值小于空穴值,那么空穴不再上浮
        return true;
    }
}
// 删除使用空穴下沉
bool MaxHeapDelete(maxHeap* obj, int* maxData)
{
    if(obj->size==0)                   // 删除数据元素之前,需要判断堆中是否还存在有效数据元素
        return false;
    else
    {
        int i = 1;                     // i 表示空穴的当前位置,空穴的初始位置为 1,但是空穴值却是堆中最后一个元素的值
        int x = obj->data[obj->size--];//获取空穴的值
        int child;                     // child 表示空穴的孩子的位置
        *maxData = obj->data[1];       // 获得被删除的值
        while(i*2<=obj->size)          // 最坏的情况空穴需要下沉到叶节点, i > obj->size/2 且 i <= obj->size 的所以节点都是叶节点
        {
            child = i*2;               // 获取空穴左孩子的位置
            if(child!=obj->size && obj->data[child]<obj->data[child+1])
                child++;               // 空穴有右孩子,且右孩子值大于左孩子,那么获取右孩子的位置
            if(obj->data[child]>x)     // 如果空穴的孩子的值大于空穴值,那么空穴下沉
            {
                obj->data[i] = obj->data[child];
                i = child;             // 空穴下沉
            }
            else                       // 如果空穴的孩子的值小于空穴值,那么空穴不再下沉,跳出循环
                break;
        }
        obj->data[i] = x;
        return true;
    }
}

C++代码

class maxHeap{
private:
    int capacity;
    int curSize;
    vector<int> data;
public:
    maxHeap(int eleNums): capacity(eleNums), curSize(0) // 构造函数
    {
        data.resize(capacity+1,0); 
        data[0] = INT_MAX;                              // 索引为0的空间不存放有效数据,只作为辅助用,这个很重要
    }

    // 插入,使用空穴上浮
    void InsertElement(int x)
    {
        if(curSize >= capacity)                        // 插入前,先判断堆中是否还有空余容量
        {
            capacity++;
            data.resize(capacity+1,x);                 // 扩容
        }
        int i = curSize+1;                             // 空穴的初始位置
        while(data[i/2] < x)                           // 只要空穴值大于空穴的父节点值,空穴就要上浮
        {                                              // 索引为 0 的数的作用在这体现,使循环条件更简单
            data[i] = data[i/2];                       // 空穴的父节点下沉
            i/=2;                                      // 空穴上浮
        }
        data[i] = x;                                   // 给空穴赋值
        curSize++;                                     // 堆中有效数据加一
    }

    //删除,使用空穴下沉
    void DeleteMaxElement(int& curMax)
    {
        if(curSize!=0)                                          // 删除前先判断堆中是否还有有效数据
        {
            curMax = data[1];                                  // 获取堆中当前最大值
            int i = 1;                                          // 空穴的初始位置
            int x = data[curSize--];                            // 空穴值取最后一个元素的值
            int child;                                          // 表示空穴孩子的位置
            while(i*2<=curSize)                                 // 空穴最多下沉到叶子节点,注意,不是一定下沉到叶子节点
            {
                child = i*2;                                    // 先取空穴的左孩子位置
                if(child!=curSize && data[child]<data[child+1]) // 找出空穴的较大的孩子
                    child++;                                    // 空穴存在右孩子,且右孩子比左孩子大
                if(x < data[child])                             // 空穴值小于空穴的孩子值,那么空穴需要下沉,否则跳出循环
                {
                    data[i] = data[child];                      // 空穴的较大的孩子上浮
                    i = child;                                  // 空穴下沉
                }
                else
                    break;

            }
            data[i] = x;                                        // 将空穴值放入空穴位置
        }
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值