【数据结构与算法】最小堆 minheap

来源:互联网 发布:戴孝禁忌知乎 编辑:程序博客网 时间:2024/06/04 17:46

最小堆与最大堆实现思路一样,只不过顺序不同,这里只记录最小堆。

最小堆的定义是,一棵完全二叉树,每一个节点都大于等于其父节点。完全二叉树是叶子都在最后一层,且尽量靠左。

实现方面可以使用链表或者数组,这里使用数组。

如果使用数组,那么下标从0开始,父节点是i,则左子树是2*i+1,右子树是2*i+2。如果子节点是i,则父节点是(i-1)/2。

minheap的操作主要有两个,一个是add,思路是,新建一个节点在最后,然后不断地和父节点比较,如果小于父节点,就交换,直到大于等于或者root。

第二个操作是输出root,那么需要把最后一个节点移至root位置,然后重新梳理minheap,因为此时可能不再shiminheap了,梳理过程用函数minheapify实现。该函数的实现思路是传入一个i参数,表明以i为根的子树需要梳理,然后让i和比i小的子节点中的较小值交换,再递归地梳理被交换的节点。

下面是代码,这里没有考虑一些边界,比如数组的大小,或者输出空的heap的情况。

public class MinHeap {private int size = 0;private int[] heap = new int[100];public void add(int data){heap[size++] = data;int i = size - 1;while(i > 0 && heap[i] < heap[(i - 1) / 2]){swap(i, (i - 1) / 2);i = (i - 1) / 2;}}public int top(){size --;int r = heap[0];swap(size, 0);minheapify(0);return r;}public void minheapify(int i){int l = 2 * i + 1;int r = 2 * i + 2;int small = i;if(l < size && heap[i] > heap[l]){small = l;}if(r < size && heap[r] < heap[small]){small = r;}if(i != small){swap(i, small);minheapify(small);}}private void swap(int i, int j){int temp = heap[i];heap[i] = heap[j];heap[j]= temp;}public int size(){return size;}}



0 0
原创粉丝点击