数据结构之堆——C++具体实现

        堆(heap)通常是一个可以被看做一棵树的数组对象。堆是非线性数据结构,相当于一维数组,有两个直接后继。堆总是满足下列性质:

  • 堆中某个结点的值总是不大于或不小于其父结点的值;

  • 堆总是一棵完全二叉树。

    下面是堆的底层算法原理实现。

1.堆数据结构定义

#define DEFAULT_CAPCITY 128 //预定义一个最大容量
typedef struct _Heap{
    int *arr; //存储堆元素的数组
    int size;//当前已存储元素个数
    int capacity; // 当前存储的容量
}Heap;

2.初始化堆

bool initHeap(Heap &heap,int*orginal,int size) //堆实例,给定数组,数组大小
{
     int capacity=DEFAULT_CAPCITY>size?DEFAULT_CAPCITY:size;
     heap.arr=new int[capacity];
     if(!heap.arr) return false;
     
     heap.capacity=capacity;
     heap.size=0;
    
     if(size>0) //如果数组里面有元素才建堆
     {
        memcpy(heap.arr,orginal,size*sizeof(int)); //最后一个参数为元素占空间大小
        heap.size=size;
        buildHeap(heap); //调用下面建堆方法
     }
    return true;
}

3.建堆

void buildHeap(Heap &heap)
{
    int i;
    for(i=heap.size/2-1;i>=0;i--)
    {
        adjustDown(heap,i); //调整堆的函数
    }
}

4.向下调整堆

void adjustDown(Heap &heap,int index)
{
    int cur=heap.arr[index];
    int parent,child;

    for(parent=index;(parent*2+1)<heap.size;parent=child)
    {
        child=parent*2+1;
        if(((child+1)<heap.size)&&(heap.arr[child]<heap.arr[child+1])) //取两个子节点中的最大结点
        {
            child++;
        }
        if(cur>=heap.arr[child]) //判断节点是否大于父节点
        {
          break;
        }
        else{
            heap.arr[parent]=heap.arr[child];
            heap.arr[child]=cur;
        }
    }
}

5.向堆中插入元素

bool insert(Heap &heap,int value)
{
     if(heap.size==heap.capacity) return false;
     
     int index=heap.size;
     heap.arr[heap.size++]=value;
     adjustup(heap,index); //向上调整方法
     return true;
}

6.向上调整堆

void adjustup(Heap &heap,int index)
{
    if(index<0||index>=heap.size) return;
    while(index>0)
    {
        int tmp=heap.arr[index];
        int parent=(index-1)/2;
        if(parent>=0)
        {
            if(temp>heap.arr[parent])
            {
                heap.arr[index]=heap.arr[parent];
                heap.arr[parent]=temp;
                index=parent;
            }else
            {
                break;
            }
        }else{
            break; 
        }
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

芷菁小可爱~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值