堆排序
2017-03-20 16:06
211 查看
最大堆结构
堆排序
什么是最大堆:1、二叉树结构 2、父节点大于其两个子节点
shiftUp(Integer[] data,int k)
向上堆排序,添加元素时使用。
shiftDown(int k)
向下堆排序,根元素被拿走时使用。
二叉树的结构有个比较重要的性质:
/** * 实现 最大堆 结构 */ public class MaxHeap { private Integer[] data; private int count; private int capacity; public MaxHeap(int capacity) { data = new Integer[capacity+1]; count = 0; this.capacity = capacity; } // 新的构造函数 public MaxHeap(Integer[] arr, int n) { this.data = new Integer[n+1]; this.capacity = n; for(int i=0;i<n;i++){ data[i+1] = arr[i]; } count = n; for(int i=count/2;i>=1;i--){// Heapify算法。将n个元素逐个插入到一个空堆中,算法复杂度是O(nlogn);heapify的过程,算法复杂度是O(n) shiftDown(i); } } int size(){ return count; } boolean isEmpty(){ return count == 0; } void insert(int item){ assert(count+1<=capacity); data[count+1] = item; count++; shiftUp(data,count); } public int extractMax(){ assert (count>0); Integer ret = data[1]; Tlt.exch(data,1,count); count--; shiftDown(1); return ret; } private void shiftUp(Integer[] data,int k) { while(k>1 && data[k/2] <data[k]){ Tlt.exch(data,k/2,k); k/=2; } } private void shiftDown(int k) { while(2*k<=count){// 保证有子节点 int j = 2*k; // 此轮循环中,data[k]和data[j]交换 if(j+1 <= count && data[j+1]>data[j]){ // 挑出最大子节点 j +=1; } if(data[k]>=data[j]){ break; } Tlt.exch(data,k,j); k = j; } } public static void main(String[] args) { MaxHeap heap = new MaxHeap(100); for(int i=0;i<15;i++){ heap.insert(StdRandom.uniform(0,100)); } while(!heap.isEmpty()){ int max = heap.extractMax(); System.out.print(max+" "); } } }
堆排序
public class HeapSort { public static void sort(Integer[] arr){ Integer n = arr.length; MaxHeap maxHeap = new MaxHeap(n); for(int i=0;i<n;i++){ maxHeap.insert(arr[i]); } for(int i=n-1;i>=0;i--){ arr[i] = maxHeap.extractMax(); } } public static void sort2(Integer[] arr){ Integer n = arr.length; MaxHeap maxHeap = new MaxHeap(arr,n); for(int i=n-1;i>=0;i--){ arr[i] = maxHeap.extractMax(); } } }
什么是最大堆:1、二叉树结构 2、父节点大于其两个子节点
shiftUp(Integer[] data,int k)
向上堆排序,添加元素时使用。
shiftDown(int k)
向下堆排序,根元素被拿走时使用。
二叉树的结构有个比较重要的性质:
父节点的下标*2 = 左子节点的下标