搞了个HeapSort类,有个类变量type确定是大顶堆还是小顶堆。
注意,用堆的时候处理的数组是0元素不用的!!
上代码:
package www.com.leetcode.specificProblem; /** * 数组的0元素不用 * @author 85060 * */ public class HeapSort { private int heapType;//0表示大顶堆,其他都是小顶堆 public HeapSort(int heapType) { this.heapType = heapType; } public void heapSort(int[] num) { makeHeap(num); for(int i = num.length - 1; i >= 2; i--) {//这个i可以理解成,要和堆顶元素交换的那个index,肯定到2就结束了 shiftDown(num, 1, i); //堆顶和堆最后的元素交换 int temp = num[1]; num[1] = num[i]; num[i] = temp; } } /** * 这个方法把传进来的数组变成堆 * @param num */ public void makeHeap(int[] num) { for(int i = (num.length - 1)/2; i >= 1; i--) {//从最后一个有孩子的结点开始,做筛选操作,直到根节点也就是1号元素(0号不用) shiftDown(num, i, num.length - 1); } } /** * 将一颗树从上到下筛选成堆的方法,前提这个根的两个子树都已经是堆了 * @param heap * @param root 开始的结点,也就是根 * @param last 结束的结点,或者说是完全二叉树最后的那个结点 */ public void shiftDown(int[] heap, int root, int last) { int rootIndexTemp = root; int leftIndexTemp, rightIndexTemp, priorChildIndexTemp; while(2 * rootIndexTemp <= last) {//保证temp表示的树的左孩子在范围之内 leftIndexTemp = 2 * rootIndexTemp; rightIndexTemp = 2 * rootIndexTemp + 1; if(rightIndexTemp > last)priorChildIndexTemp = leftIndexTemp;//没有右孩子,那么孩子之间的优先者就直接左孩子 else priorChildIndexTemp = prior(heap[leftIndexTemp], heap[rightIndexTemp]) ? leftIndexTemp : rightIndexTemp; if(prior(heap[rootIndexTemp], heap[priorChildIndexTemp])) return;//比孩子结点优先,筛选结束 else { //交换操作 int temp = heap[rootIndexTemp]; heap[rootIndexTemp] = heap[priorChildIndexTemp]; heap[priorChildIndexTemp] = temp; rootIndexTemp = priorChildIndexTemp;//指针向下走,直到指定的last范围内的叶节点为止 } } } /** * 看是大顶堆还是小顶堆,决定是大于优先还是小于优先 * @param a * @param b * @return */ private boolean prior(int a, int b) { if(heapType == 0)return a >= b; else return a <= b; } public static void main(String[] args) { int[] a = {0,3,6,1,8,12,55};//注意0号元素不用 HeapSort heapSort = new HeapSort(0);//大顶堆,按正序排列 heapSort.heapSort(a); show(a); } public static void show(int[] array) { for(int i= 1; i < array.length; i ++) { System.out.print(array[i] + " "); } System.out.println(); } /** * 插入后调整堆的算法 * @param heap * @param newEleIndex 新元素的序号 */ public void adjustHeapAfterInsert(int[] heap, int newEleIndex) { int indexTemp = newEleIndex; while(indexTemp > 1 && prior(heap[indexTemp], heap[indexTemp / 2])) {//还没到根节点&&比双亲结点的优先级大——就要交换和指针上移 int temp = heap[indexTemp]; heap[indexTemp] = heap[indexTemp / 2]; heap[indexTemp / 2] = temp; indexTemp = indexTemp / 2; } } }