一.小根堆
大根堆实际上就是一组数据 可以按照二叉树的逻辑结构进行建立,并且进行相关的算法
二.建立小根堆
如何建立小根堆
大根堆的意思就是堆顶元素永远比它左右孩子元素大,也就是说 首先比较俩孩子节点,找到其中最大的元素,然后这个最大的元素和堆顶元素(父亲节点)进行比较。然后大的当父亲,小的当孩子去(也就是交换元素)。
数组中每个元素都是有下标的, 70的下标是0
56的下标是1
30的下标是2 这在左上图 指的是父亲节点
那么如何获得每一棵树的父亲节点呢?
我们发现我们只需要获得 0 1 2下标就可以了
通过观察可以发现 (数组长度 - 1 - 1) / 2 可以得到 30节点的下标,也就是2
代码如下
public void createHeap(int[] array) { //传建一个大根堆 for (int parent = (array.length - 1 - 1) / 2; parent >=0 ; parent--) { shiftDown(array,parent,array.length); } }
父亲节点就是 (数组长度 - 1 - 1) / 2
我们首先要做的就是要调整每一棵小树 也就是0 1 2 下标的树
那么如何得到孩子节点呢?
举个例子 我想要通过 56(1) 来找到15(4) 和 25 (3)
父亲节点*2 + 1 就能找到 25 那么 15也能找到
代码如下
public void shiftDown(int parent,int length) { ; //向下开始调整 先标记最后一个父节点,依次往上调整 int child = 2 * parent + 1; //此时的child下标为5 //什么时候停止循环? 当我的child大于当前数组下标的时候 while (child < length) { //开始判断左右孩子节点值的大小 //此处需要注意 如果当前左孩子就是当前最大的下标,那么在进行比较的时候会出现数组越界异常 //所以有可能子树只有一个左孩子 if(child+1 < length && elem[child] > elem[child + 1]) { child++; } //开始判断最大的孩子和父亲节点 if(elem[child] < elem[parent]) { //如果孩子节点比父亲节点小,开始交换 int tmp = elem[child]; elem[child] = elem[parent]; elem[parent] = tmp; //交换完成之后 继续向下调整parent树,因为不知道5的下面是否还有子树 parent = child; child = parent * 2 + 1; } else { //如果父亲节点大于当前最大的孩子节点,说明父亲节点是最大的,无需比较与交换 break; } } } public void swap(int[] array,int index1 ,int index2) { //交换函数 int tmp = array[index1]; array[index1] = array[index2]; array[index2] = tmp; }
此时我们就建立好了一个小根堆