目录:

1、定义

2、个性

3、名词

4、实操

注释:

一、定义:

堆(heap)是计算机科学中一类非凡的数据结构的统称。堆通常是一个能够被看做一棵树的数组对象。n个元素的序列{k1,k2,ki,…,kn}当且仅当满足以下关系时,称之为堆。(ki<=k2i且ki<=k2i+1)或者(ki>=k2i且ki>=k2i+1)解析:我在这个文章中用的是数组来实现堆,我就用数组举例:例如:一个数组[2,1,3,4,5,6,7,8]这个能够当成一个相似齐全二叉树的构造,根当初是2,但还不是堆,而堆分成最大堆,和最小堆,咱们以最小堆举例,咱们想让这个齐全二叉树的数组,变成堆,就须要调整,让它们合乎根<=左结点并且根<=右结点,在这里调整咱们也分为两种,咱们能够用向上调整或者向下调整,当初咱们应用向下调整法,从顶开始往下调整,而后向下调整只有都须要合乎堆得属性,就能够失去最小堆[1,2,3,4,5,6,7,8];

以上对定义以及大抵逻辑解析实现,接下来咱们齐全依据这个逻辑解析做实操代码,请急躁往下看

二、个性:

1. 堆中某个结点的值总是不大于或不小于其父结点的值2. 堆总是一棵齐全二叉树3. 堆是非线性数据结构,相当于一维数组,有两个间接后继

三、名词:

最大堆/大根堆/大顶堆:
根结点最大的堆

最小堆/小根堆/小顶堆:
根结点最小的堆

四、实操:

1、创立堆接口类:

/** * 堆接口类 * 利用场景: * 优先队列 * 取最大值/最小值 * @author gxw * @date 2021/11/4 早晨21:58 */public interface Heap {    //构建堆办法    void buildHeap(int[] arr);    //增加元素    void add(int g);    //替换元素,将第i个地位的元素值替换为g    void replace(int i, int g);    //删除顶元素    boolean pop();    //向上堆排序    void shift_up(int now);    //向下堆排序    void shit_down(int now);    //获取顶值    int getTopValue();    //展现堆    void display();}

2、创立最大堆实现类:

/** * 最大堆,也称大跟堆,也称大顶堆 * @author gxw * @date 2021/11/4 早晨22:21 */public class MaxHeap implements Heap {    //堆数组    private int[] heapArr;    //堆总结点    private int size;    //堆深    private int depth;    //堆最大寄存结点    private int maxSize;    public MaxHeap(int maxSize){        this.maxSize = maxSize;        this.heapArr = new int[maxSize];    }    @Override    public void buildHeap(int[] arr) {        if(arr == null && arr.length <= 0)            return;        //进行构建最大堆        for (int g : arr) {            add(g);        }    }    @Override    public void add(int g) {        //先判断堆是否曾经满了        if(size == maxSize)            return;        //增加到堆得最初        heapArr[size] = g;        //结点数加1        size++;        //树深判断是否能够加,如果 2^depth -1 < size        // (原理:通过堆深计算所有总结点值,如果小于以后的堆有结点值,天然须要加1)        if(Math.pow(2, depth) - 1 < size)            depth++;        //向上调整        shift_up(size);    }    @Override    public void replace(int i, int g) {//i 代表逻辑地位,不代表数组角标,还需减一        //判断如果角标不在正确范畴内,不能够操作        if(i < 0 || i > size)            return;        //批改值        heapArr[i - 1] = g;        //向上调整        shift_up(i);    }    @Override    public boolean pop() {        if(size == 0)            return false;        //移除最大值(大根值),并将最初一个值赋给大根值        heapArr[0] = heapArr[size - 1];        //结点数量减一        size--;        //向下调整, 1代表逻辑第一个值,不代表数组第一个        shit_down(1);        return true;    }    @Override    public void shift_up(int now) {//now 逻辑数值,不代表物理数组角标,还需减一        for(int i = 0;i < depth - 1;i++){            //获取父结点的地位,因为是数组所以减一            int parentIndex = (int) Math.floor(now / 2) - 1;            //replace 办法专有,如果父角标小于0,阐明到顶完结            if(parentIndex < 0)                break;            int nowIndex = now - 1;//因为是数组,所以角标-1            //判断以后数是否大于父结点,如果大于就替换            if(heapArr[nowIndex] > heapArr[parentIndex]){                //替换                int temp = heapArr[parentIndex];                heapArr[parentIndex] = heapArr[nowIndex];                heapArr[nowIndex] = temp;                //而后从以后持续往上判断                now = parentIndex + 1;            }else{//如果不大于,就完结调整                break;            }        }    }    @Override    public void shit_down(int now) {//now 逻辑数值,不代表物理数组角标,还需减一        for(int i = 0;i < depth - 1;i++){            //获取左右子结点值最大的地位            int sonIndex = heapArr[2 * now - 1] > heapArr[2 * now ] ? 2 * now  - 1 : 2 * now ;            int nowIndex = now - 1;//因为是数组,所以角标-1            //判断以后数是否小于子结点,如果小于就替换            if(heapArr[nowIndex] < heapArr[sonIndex]){                //替换                int temp = heapArr[sonIndex];                heapArr[sonIndex] = heapArr[nowIndex];                heapArr[nowIndex] = temp;                //而后从以后持续往下判断                now = sonIndex + 1;            }else{//如果不小于,就完结调整                break;            }        }    }    @Override    public int getTopValue() {        return heapArr[0];    }    @Override    public void display() {        for(int i = 0;i < size;i++){            System.out.print(heapArr[i] + " ");        }        System.out.println("");    }}

3、创立最小堆实现类:

/** * 最小堆,也称小跟堆,也称小顶堆 * @author gxw * @date 2021/11/4 早晨22:22 */public class MinHeap implements Heap {    //堆数组    private int[] heapArr;    //堆总结点    private int size;    //堆深    private int depth;    //堆最小寄存结点    private int maxSize;    public MinHeap(int maxSize){        this.maxSize = maxSize;        this.heapArr = new int[maxSize];    }    @Override    public void buildHeap(int[] arr) {        if(arr == null && arr.length <= 0)            return;        //进行构建最小堆        for (int g : arr) {            add(g);        }    }    @Override    public void add(int g) {        //先判断堆是否曾经满了        if(size == maxSize)            return;        //增加到堆得最初        heapArr[size] = g;        //结点数加1        size++;        //树深判断是否能够加,如果 2^depth -1 < size        // (原理:通过堆深计算所有总结点值,如果小于以后的堆有结点值,天然须要加1)        if(Math.pow(2, depth) - 1 < size)            depth++;        //向上调整        shift_up(size);    }    @Override    public void replace(int i, int g) {//i 代表逻辑地位,不代表数组角标,还需减一        //判断如果角标不在正确范畴内,不能够操作        if(i < 0 || i > size)            return;        //批改值        heapArr[i - 1] = g;        //向上调整        shift_up(i);    }    @Override    public boolean pop() {        if(size == 0)            return false;        //移除最小值(大根值),并将最初一个值赋给大根值        heapArr[0] = heapArr[size - 1];        //结点数量减一        size--;        //向下调整, 1代表逻辑第一个值,不代表数组第一个        shit_down(1);        return true;    }    @Override    public void shift_up(int now) {//now 逻辑数值,不代表物理数组角标,还需减一        for(int i = 0;i < depth - 1;i++){            //获取父结点的地位,因为是数组所以减一            int parentIndex = (int) Math.floor(now / 2) - 1;            //replace 办法专有,如果父角标小于0,阐明到顶完结            if(parentIndex < 0)                break;            int nowIndex = now - 1;//因为是数组,所以角标-1            //判断以后数是否小于父结点,如果小于就替换            if(heapArr[nowIndex] < heapArr[parentIndex]){                //替换                int temp = heapArr[parentIndex];                heapArr[parentIndex] = heapArr[nowIndex];                heapArr[nowIndex] = temp;                //而后从以后持续往上判断                now = parentIndex + 1;            }else{//如果不大于,就完结调整                break;            }        }    }    @Override    public void shit_down(int now) {//now 逻辑数值,不代表物理数组角标,还需减一        for(int i = 0;i < depth - 1;i++){            //获取左右子结点值最小的地位            int sonIndex = heapArr[2 * now - 1] < heapArr[2 * now ] ? 2 * now  - 1 : 2 * now ;            int nowIndex = now - 1;//因为是数组,所以角标-1            //判断以后数是否大于子结点,如果大于就替换            if(heapArr[nowIndex] > heapArr[sonIndex]){                //替换                int temp = heapArr[sonIndex];                heapArr[sonIndex] = heapArr[nowIndex];                heapArr[nowIndex] = temp;                //而后从以后持续往下判断                now = sonIndex + 1;            }else{//如果不小于,就完结调整                break;            }        }    }    @Override    public int getTopValue() {        return heapArr[0];    }    @Override    public void display() {        for(int i = 0;i < size;i++){            System.out.print(heapArr[i] + " ");        }        System.out.println("");    }}

4、测试:

public static void main(String[] args) {    int[] arr = {2,3,3,2,6,7,11,11};    /**     * 最大堆,大根堆,大顶堆     */    MaxHeap maxHeap = new MaxHeap(20);    //构建最大堆    System.out.println("初始构建最大堆");    maxHeap.buildHeap(arr);    maxHeap.display();    //增加数    System.out.println("增加9");    maxHeap.add(9);    maxHeap.display();    //替换值    System.out.println("将第6个数值替换成10");    maxHeap.replace(6, 10);    maxHeap.display();    //移除最大值    System.out.println("移除最大值");    maxHeap.pop();    maxHeap.display();    //获取最大值    System.out.println("获取最大值");    System.out.println(maxHeap.getTopValue());    /**     * 最小堆,小根堆,小顶堆     */    MinHeap minHeap = new MinHeap(20);    //构建最小堆    System.out.println("初始构建最小堆");    minHeap.buildHeap(arr);    minHeap.display();    //增加数    System.out.println("增加1");    minHeap.add(1);    minHeap.display();    //替换值    System.out.println("将第6个数值替换成10");    minHeap.replace(6, 10);    minHeap.display();    //移除最小值    System.out.println("移除最小值");    minHeap.pop();    minHeap.display();    //获取最小值    System.out.println("获取最小值");    System.out.println(minHeap.getTopValue());}

5、后果:

—————————————END———————————
本文为数据结构堆得学习总结,心愿能够帮忙到诸位,如果内容有问题,还请贵人指出,谢谢!