基本数据结构 最小堆

最小堆,是完全二叉树,其基本定义是任何一个节点小于其左右子树的节点

常见操作:加入一个值,取最小值,删除最小值

 

加入一个值,直接加入到末尾a[size++]  然后该元素上浮到合适位置

最大值即根节点 a[0]

删除最小值,让末尾元素填充到a[0]  然后该元素下沉到合适位置

下沉过程中,选取左右子节点的最小值,上浮(任满足节点大于左右子树)

易错点,树中没有节点,以及下沉过程中,是否存在左右子树的判断(即基本的数组区间判断)

class heap
{
public:
    int arr[1000];
    int size=0;


    void push(int data) //新来元素填充到末尾 然后上浮到合适位置
    {
        arr[size] = data;
        up(size);
        size++;
    }
    void up(int index)  //arr[index]位置元素上浮
    {
        
        if (index == 0)
            return;
        
        int flag = arr[index];
        while (((index - 1) / 2) >= 0 && arr[(index - 1) / 2] > flag)
        {
          
            arr[index] = arr[(index - 1) / 2];
            index = (index - 1) / 2;
            if (index == 0)
                break;
        }
        arr[index] = flag;//最终填入位置

    }
    int min()
    {
        return arr[0];
    }
    void del()   //删除根元素 最小元素后   最后元素填上,然后下沉
    {
        if(size == 0 || size == 1)
        {
            size = 0;
            return;
        }
        arr[0] = arr[size - 1];//将最后一个填充到根顶部
        size--;
        down(0);//从根节点开始下沉
            


    }
    void down(int index)  //arr[index]位置元素下沉
    {
        if (index * 2 + 1 >= size)  //已经到叶子节点了
            return;
        else
        {
            if (index * 2 + 2 < size) //还存在右子树
            {
                if (arr[index * 2 + 1] < arr[index * 2 + 2])
                {
                    if (arr[index * 2 + 1] > arr[index])
                        return;
                    else
                    {
                        int tmp = arr[index];
                        arr[index] = arr[index * 2 + 1];
                        arr[index * 2 + 1] = tmp;
                        down(index * 2 + 1);
                    }

                }
                else
                {
                    if (arr[index * 2 + 2] > arr[index])
                        return;
                    else
                    {
                        int tmp = arr[index];
                        arr[index] = arr[index * 2 + 2];
                        arr[index * 2 + 2] = tmp;
                        down(index * 2 + 2);
                    }

                }
            }
            else //不存在右子树
            {
                if (arr[index * 2 + 1] > arr[index])
                    return;
                else
                {
                    int tmp = arr[index];
                    arr[index] = arr[index * 2 + 1];
                    arr[index * 2 + 1] = tmp;
                  //  down(index * 2 + 1);
                }

            }

        }

    }


};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值