堆分爲大頂堆,和小頂堆。 什麼是堆? 堆能夠當作是一棵二叉樹,二叉樹的元素是一個數組不斷的從左到右輪訓放置。若是是大頂堆,則大的數放上面一層,小的數放下面一層。上一層的數,必定大於下一層的數。小頂堆則相反。java
那麼,如何實現一個大頂堆?這裏我用一個鏈表來實現。數組
實現堆很簡單,只要牢記他的原理就好了。測試
添加新元素:添加至數組末尾。而後對這個末尾節點不斷的向上層冒泡。直到找到一個合適的節點放置。this
刪除元素:從數組末尾取出一個元素對當前要刪除的元素進行覆蓋,後刪除末尾的元素。而後從當前節點不斷的向下冒泡。就能找到一個合適的位置進行放置。spa
上層元素和下層元素之間的關係:上層元素(索引爲:index )和下層元素索引存在 2 * index + 1(左孩子節點) 2 * index + 2(右孩子節點)的關係。code
實現源碼:blog
package heap; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.junit.Test; public class Heap { private List<Integer> heapArray; public Heap() { super(); this.heapArray = new ArrayList(); } //添加元素進堆 public void Push(Integer x) { heapArray.add(x); trickleUp(heapArray.size()-1); } //刪除元素 public void Pop() { heapArray.set(0, heapArray.get(heapArray.size()-1)); heapArray.remove(heapArray.size()-1); trickleDown(0); } //取出根數據 public Integer Top() { return heapArray.get(0); } //判斷是否爲空 public boolean isEmpty() { if(Top() == null) { return true; } return false; } //向上滲透 public void trickleUp(int index) { int parent = (index-1) / 2; Integer bottom = heapArray.get(index); while(index > 0 && heapArray.get(parent) < bottom) { heapArray.set(index, heapArray.get(parent)); index = parent; parent = (parent - 1) / 2; } heapArray.set(index, bottom); } //向下滲透 public void trickleDown(int index) { Integer top = heapArray.get(0); int lagerChild; while(index < heapArray.size()/2) { int leftChild = index * 2 + 1; int rightChild = index * 2 + 2; if(rightChild < heapArray.size() && heapArray.get(leftChild) < heapArray.get(rightChild)) { lagerChild = rightChild; }else { lagerChild = leftChild; } if(top >= heapArray.get(lagerChild)) { break; } heapArray.set(index, heapArray.get(lagerChild)); index = lagerChild; } heapArray.set(index, top); } }
測試程序:排序
@Test public void fun() { Heap p = new Heap(); p.Push(20); p.Push(30); p.Push(15); System.out.println(p.Top()); p.Push(90); p.Push(35); System.out.println(p.Top()); p.Pop(); System.out.println(p.Top()); }
測試結果:索引
30 90 35
堆排序:rem
堆排序很是簡單,利用大頂堆的頂必定是堆元素裏面的最大值。那麼咱們就能夠將一系列數據存進去,再不斷的取出頂元素。取除的元素就是一個排好序的元素。
源碼:
public static void main(String[] args) { Heap h = new Heap(); h.Push(2); h.Push(1); h.Push(4); h.Push(6); System.out.println(h.Top()); h.Pop(); System.out.println(h.Top()); h.Pop(); System.out.println(h.Top()); h.Pop(); System.out.println(h.Top()); }
結果:
6 4 2 1
至此,堆排序就已經作好了。