使用数组实现一个小顶堆

堆也叫优先队列,可以在\(\mathcal{O(1)}\)时间里得到堆中的最小/大元素。堆在各种编程语言中都有实现,c++STL里面有priority_queue,java中是Priority_Queue,python里提供了heapp模块实现对堆的各种操作。
堆可以分为小顶堆和大顶堆,顾名思义,小顶堆堆顶存储堆中的最小值,大顶堆堆顶存储堆中的最大值,下面使用数组模拟一个小顶堆的实现,大顶堆类似。
要实现一个堆,必须具备add操作(往堆中添加元素),peek操作(返回堆顶元素),pop操作(返回堆顶元素并将该元素删除)三个操作,而三个操作又是由up操作和down操作来实现。
up操作将当前元素往上移动,down操作将当前元素往下移动。

class Heap {
    int[] heap = new int[1010];//小顶堆
    int sz = 0;//当前堆中的元素数目
    void swap(int a, int b) {
        int c= heap[a];
        heap[a] = heap[b];
        heap[b] = c;
    }

    void up(int u) {
        int f = u / 2;//当前结点的父结点所对应的下标
        //如果当前结点比父结点小 交换当前结点与父结点 并递归处理父结点
        if(f != 0 && heap[f] > heap[u]) {
            swap(f, u);
            up(f);
        }
    }

    void down(int u) {
        int cur = u;
        int l = u * 2;
        int r = u * 2 + 1;
        //如果当前结点比左/右子结点大 交换当前结点与左/右子结点  并递归处理左/右子结点
        if(l <= sz && heap[l] < heap[cur]) cur = l;
        if(r <= sz && heap[r] < heap[cur]) cur = r;
        if(cur != u) {
            swap(cur, u);
            down(cur);
        }
    }

    void add(int x) {
        heap[++sz] = x;//为方便起见 在数组的末尾添加新元素
        up(sz);
    } 

    int peek() {
        return heap[1];//返回堆顶元素
    }

    int pop() {
        int res = heap[1];
        heap[1] = heap[sz--];//将数组结尾元素移至堆顶
        down(1);
        return res;
    }
}
posted @ 2023-10-28 13:11  梦醒时风  阅读(81)  评论(0编辑  收藏  举报