堆操作(1)-堆中插入元素,刪除元素


一、堆定義

堆是一個優先隊列,右二叉樹來表示,其特性:

  1. 是一顆完全二叉樹
  2. 任意節點的元素是其子樹的最大值(最小值)
    1. 最大值,大頂堆
    2. 最小值,小頂堆

示例:

完全二叉樹用數組繼續存儲。定義如下:

public class HeapStruct {
    private Integer[] elements;//用數組存儲
    private Integer capacity;//帶表數組的容量

    public HeapStruct(Integer capacity) {
        this.capacity = capacity;
        this.elements = new Integer[capacity];
    }

    public Integer[] getElements() {
        return elements;
    }

    public Integer getCapacity() {
        return capacity;
    }
    //代表實際存儲的元素
    public Integer getSize() {
        int index = 0;
        for (Integer data : elements) {
            if (data != null) {
                index++;
            }
        }
        return index;
    }
}

二、向堆中插入一個元素

插入一個元素后要保證還是一個堆,就要保證對的兩個屬性不能變(完全二叉樹和任意元素的值大於其子樹的值)。

  1. 保證完全二叉樹:首先將新插入的元素插入的數組的最后面。
  2. 保證如何節點元素大於其子樹:在1的基礎上繼續調整,如果新插入的數據大於其父節點,和父節點繼續交換,一直比較到小於父節點或者新插入的數據變成整個二叉樹的根節點為止。
    public static void insert(HeapStruct heapStruct, Integer data) {
        if (heapStruct.getCapacity().equals(heapStruct.getSize())) {
            return;//full
        }
        int currentIndex = heapStruct.getSize();//放到最后
        Integer[] elements = heapStruct.getElements();
        while (currentIndex > 0) {
            int parentIndex = currentIndex / 2;//父節點對應的index
            if (elements[parentIndex] < data) {//父節點的元素比插入的值要小。
                elements[currentIndex] = elements[parentIndex];//父節點下移。
                currentIndex = parentIndex;//繼續往上找
            } else {
                break;
            }
        }
        elements[currentIndex] = data;
    }

三、從堆中刪除一個元素

堆的刪除只在對頂進行。刪除后還得保證是一個堆。

具體思路是。

  1. 對頂元素直接刪除后返回
  2. 把最后一個元素放置到堆頂。
  3. 然后用堆頂元素和左右兒子進行對比,把三者最大的和堆頂元素進行交換【最大的兒子上移】。
public static Integer deleteMax(HeapStruct heapStruct) {
        if (heapStruct == null || heapStruct.getSize() == 0) {
            return null;
        }
        Integer[] elements = heapStruct.getElements();
        Integer maxValue = elements[0];//直接刪除堆頂返回
        Integer finalValue = elements[heapStruct.getSize() - 1];//最后一個元素,當做堆頂,持續和左右兒子進行對比
        int parent = 0;
        while (parent * 2 <= heapStruct.getSize() - 1) {
            int child = parent * 2 + 1;
            if (child > heapStruct.getSize() - 1 && elements[child].compareTo(elements[child + 1]) < 0) {
                child = child + 1;//右兒子大。最大的兒子找到
            }
            if (finalValue.compareTo(elements[child]) > 0) {//最后一個元素和最大的兒子進行比較,如果最后的元素大,說明可以做頂,找到了位置。
                break;
            } else {
                elements[parent] = elements[child];//兒子大,兒子上移。持續下一輪的對比。
                parent = child;
            }
        }
        elements[parent] = finalValue;
        elements[heapStruct.getSize() - 1] = null;
        return maxValue;
    }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM