【数据结构】堆,堆的建立,插入以及删除(以大堆为例)

目录

1.堆的性质:

2.堆的存储方式

 2.1大堆和小堆存储示意图

3.堆的创建(以大堆为例)

1.创建一个线性表用来存放数据

2.堆的插入

图解:

3.堆的删除

图解:


1.堆的性质:

        堆中某个节点的值总是不大于或不小于其父节点的值;
        堆总是一棵完全二叉树

 

2.堆的存储方式

从堆的概念可知, 是一棵完全二叉树,因此可以层序的规则采用顺序的方式来高效存储

 2.1大堆和小堆存储示意图

3.堆的创建(以大堆为例)

1.创建一个线性表用来存放数据

public class MaxHeap {

    //存放元素的数组
    private List<Integer> data;

    //有效元素个数
    private int size;

    public MaxHeap(){
        this(3);
    }

    public MaxHeap(int capacity) {
        this.data = new ArrayList<>(capacity);
    }
}

2.堆的插入

1.先将元素插入到堆的末尾,即最后一个孩子之后

2.插入之后如果堆的性质遭到破坏,将新插入的节点顺着双亲往上调整到合适的位置即可

图解:

 

    // 向最大堆中添加元素
    public void add(int val){
        //尾插
        data.add(val);
        size++;
        //元素上浮
        siftUp(size - 1);
    }

    private void siftUp(int k) {
        while(k > 0 && data.get(k) > data.get(parent(k))){
            swap(k,parent(k));
            k = parent(k);
        }
    }

    private void swap(int i, int j){
        int temp = data.get(i);
        data.set(i,data.get(j));
        data.set(j,temp);
    }

3.堆的删除

堆的删除一定删除的是堆顶元素,具体如下:

        1.将对顶元素与最后一个元素交换

        2.将堆中有效元素个数减少一个

        3.对堆顶元素向下调整

图解:

 

    //删除最大元素
    public int delete(){
        //头尾元素交换,size--
        int val = data.get(0);
        data.set(0,data.get(this.size - 1));
        size--;
        //元素下沉
        shiftDown(0);
        data.remove(size);

        return val;
    }

    private void shiftDown(int k) {
        while (rightChild(k) <= size && 
                (data.get(k) < data.get(leftChild(k)) ||
                        data.get(k) < data.get(rightChild(k)))) {
            //判断左右子树谁大
            if (data.get(leftChild(k)) > data.get(rightChild(k))) {
                swap(k, leftChild(k));
                k = leftChild(k);
            } else {
                swap(k, rightChild(k));
                k = rightChild(k);
            }
        }
    }

    private void swap(int i, int j){
        int temp = data.get(i);
        data.set(i,data.get(j));
        data.set(j,temp);
    }

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值