最小堆算法代码
public class SiftUpComparable { /** * 构建最小堆代码 * @param index 将要入队的数组的角标 * @param value 将要入队的值 * @param array 数组 */ public static void siftUpComparable(int index,int value,Integer[] array){ while(index>0){ // 得到父角标位置 int parent = (index-1)>>>1; // 用父节点的值和将要入队的值进行比较,如果比父节点的值小则和父节点进行交换,因为这里构建的事小顶堆,所以要比较和交换比父节点的小的 // 如果父节点比将要插入的数据小,则直接退出 if(value>array[parent]){ break; } // 此时表示将要入队的节点数据比父节点的值要小,需要交换 // 把父节点的值拿出来,赋值给将要插入的数组角标的位置 int parentValue = array[parent]; array[index] = parentValue; // 因为需要和父节点交换,因此使角标交换 index = parent; } array[index] = value; } /** * 获取堆顶元素 * @param array * @return */ public static int siftDownComparable(Integer[] array){ int n= array.length -1; // 弹出的堆顶元素 最小的 int topValue = array[0]; // 最小堆中最后一个元素 int endKey = array[n]; // 将尾节点置为null array[n] = null; if(n<=0 ){ return 0; } // 循环次数为整个数据长度减一的一半,因为比较左节点从上到下依次比较,比较一次为一次循环,次数为 n>>>1 int half = n>>>1; // 每次比较交换的的初始脚标,刚开始要从堆顶开始,也是 0,每次的值都是下一级节点中最小的那个值 int k = 0 ; while(k<half){ //获取下一级左节点的脚标,child永远指向下一级两个节点中最小的节点角标 int child = (k<<1)+1; //获取下一级右节点的脚标 int right = child+1; // 获取下一级左节点的值 远指向下一级两个节点中最小的节点的值 int c = array[child]; // 如果right大于n,则证明此时没有右节点了 if(right<n && array[child]>array[right]){ c = array[child=right]; } // 如果尾节点的值小于子节点的值,则退出本次循环,尾节点的值是要放入首节点角标为0的位置的 if(endKey<c){ break; } // 如果尾节点的值大于子节点的值,则需要交换,将首节点的值替换为比其小的子节点的值 array[k] = c; // 将k的值下移为child k = child; } // 将尾节点放入到合适的位置 array[k] = endKey; return topValue; } public static void main(String[] args) { Integer[] array = new Integer[5]; Random random = new Random(); System.out.println("入队 "); for (int i = 0; i < 5; i++) { int value = random.nextInt(100); System.out.print(value+" "); siftUpComparable(i, value, array); } print(array); System.out.println(); System.out.println("出队"); System.out.println("出队的值 = "+siftDownComparable(array)); print(array); } public static void print( Integer[] array){ System.out.println(); for (int k=0;k<array.length;k++){ System.out.print(array[k]+" "); } } }