1.堆:堆是一種樹,由它實現的優先級隊列的插入和刪除的時間複雜度都是O(logn),用堆實現的優先級隊列雖然和數組實現相比較刪除慢了些,但插入的時間快的多了。當速度很重要且有不少插入操做時,能夠選擇堆來實現優先級隊列。
2.java的堆和數據結構堆:java的堆是程序員用new能獲得的計算機內存的可用部分。而數據結構的堆是一種特殊的二叉樹。
3.堆是具備以下特色的二叉樹:
3.1.它是徹底二叉樹,也就是說除了樹的最後一層節點不須要是滿的,其餘的每一層從左到右都必須是滿的。java
3.1.1.徹底二叉樹圖解:node
3.2.它經常用數組實現。程序員
3.2.1.數組和堆的對應關係示意圖:算法
3.3.堆中每個節點都知足堆的條件,也就是說每個關鍵字的值都大於或等於這個節點的子節點的關鍵字值。
堆是徹底二叉樹的事實說明了表示堆的數組中沒有空項,即從0-->n-1的每一個數據單元都有數據項。
4.堆在存儲器中的表示是數組,堆只是一個概念上的表示。數組
5.堆的弱序:堆和二叉搜索樹相比是弱序的,在二叉搜索樹中,當前節點的值老是比左子節點的值大,卻比它的右子節點的值小,所以按序遍歷相對容易。而堆的組織規則弱,它只要求從根到葉子節點的每一條路徑,節點都是按降序排列的。同一節點的左右子節點都沒有規律。所以,堆不支持按序遍歷,也不能在堆上便利的查找指定關鍵字,由於在查找的過程當中,沒有足夠的信息決定選擇經過節點的兩個那一個走向下一層。它也不能在少於O(logn)的時間內刪除一個指定的節點,由於沒有辦法找到這個節點。所以,堆的這種近乎無序的規則彷佛毫無用處,不過對於快速移除最大節點的操做,以及快速插入新節點的操做,這種順序已經足夠了。這些操做是使用堆做爲優先級隊列所須要的所有操做。數據結構
6.移除操做:移除是指刪掉關鍵字值最大的節點,即根節點。移除思路以下:dom
6.1.移走根,ide
6.2.把左後一個節點移到根的位置,測試
6.3.一直向下篩選這個節點,知道它在一個大於它的節點之下,小於它的節點之上爲止。spa
6.4.過程圖解:
說明:在被篩選節點的每一個暫時停留的位置,向下篩選的算法老是要檢查那一個子節點更大,而後目標節點和較大的子節點交換位置,若是要把目標節點和較小的子節點交換,那麼這個子節點就會變成大子節點的父節點,這就違背了堆的條件。
7.堆的插入:插入使用向上篩選,節點最後插入到數組最後第一個空着的單元中,數組容量大小增長1。
7.1.插入圖解:
說明:向上篩選的算法比向下篩選的算法相對簡單,由於它不須要比較兩個子節點關鍵字值的大小,節點只有一個父節點。目標節點主要和它的父親節點換位便可。
7.2.不是真的交換:
8.用數組表示一棵樹時,若是數組中節點的索引位x,則
a.它的父節點的下標是:(x-1)/2;
b.它的左子節點的下標爲2*x + 1;
c.它的右子節點的下標是2*x + 2;
9.堆的代碼:
9.1.Node.java
1 package com.cn.heap; 2 /** 3 * 堆的節點類 4 * @author Administrator 5 * 6 */ 7 public class Node { 8 private int iData; 9 public Node(int id){ 10 iData = id; 11 } 12 public int getkey(){ 13 return iData; 14 } 15 public void setkey(int id){ 16 iData = id; 17 } 18 }
9.2.Heap.java
1 package com.cn.heap; 2 /** 3 * 堆的實現類 4 * @author Administrator 5 * 6 */ 7 public class Heap { 8 private Node[] heapArray; 9 private int maxSize; 10 private int currentSize; 11 public Heap(int mx){ 12 maxSize = mx; 13 heapArray = new Node[maxSize]; 14 currentSize = 0; 15 } 16 public boolean isEmpty(){ 17 return currentSize == 0 ; 18 } 19 public boolean insert(int key){ 20 if (currentSize == maxSize) 21 return false; 22 Node thenode = new Node(key); 23 heapArray[currentSize] = thenode; 24 trickleUp(currentSize ++); 25 return true; 26 } 27 public void trickleUp(int index){ 28 int parent = (index - 1) / 2; 29 Node bottom = heapArray[index]; 30 while (index > 0 && heapArray[parent].getkey() < bottom.getkey()){ 31 heapArray[index] = heapArray[parent]; 32 index = parent; 33 parent = (parent - 1) / 2; 34 } 35 heapArray[index] = bottom; 36 } 37 public Node remove(){ 38 Node root = heapArray[0]; 39 heapArray[0] = heapArray[-- currentSize]; 40 trickleDown(0); 41 return root; 42 } 43 public void trickleDown(int index){ 44 int largeChild; 45 Node top = heapArray[index]; 46 while (index < currentSize / 2){ 47 int leftChild = 2 * index + 1; 48 int rightChild = 2 * index + 2; 49 if (rightChild < currentSize && heapArray[leftChild].getkey() < heapArray[rightChild].getkey()) 50 largeChild = rightChild; 51 else 52 largeChild = leftChild; 53 if (top.getkey() >= heapArray[largeChild].getkey()) 54 break; 55 heapArray[index] = heapArray[largeChild]; 56 index = largeChild; 57 } 58 heapArray[index] = top; 59 } 60 public boolean change(int index,int newvalue){ 61 if (index < 0 || index >=currentSize) 62 return false; 63 int oldvalue = heapArray[index].getkey(); 64 heapArray[index].setkey(newvalue); 65 if (oldvalue < newvalue) 66 trickleUp(index); 67 else 68 trickleDown(index); 69 return true; 70 } 71 public void displayHeap(){ 72 System.out.print("heapArray:"); 73 for (int i = 0; i < currentSize; i++) { 74 if (heapArray[i] != null) 75 System.out.print(heapArray[i].getkey()+" "); 76 else 77 System.out.print("--"); 78 } 79 System.out.println(""); 80 int nBlanks = 32; 81 int itemsPerrow = 1; 82 int column = 0; 83 int j = 0; 84 String dots = "........................"; 85 System.out.println(dots + dots); 86 while (currentSize > 0){ 87 if (column == 0) 88 for (int i = 0; i < nBlanks; i++) { 89 System.out.print(" "); 90 } 91 System.out.print(heapArray[j].getkey()); 92 if (++ j == currentSize) 93 break; 94 if (++ column == itemsPerrow){ 95 nBlanks /= 2; 96 itemsPerrow *= 2; 97 column = 0; 98 System.out.println(); 99 } 100 else 101 for (int i = 0; i < nBlanks * 2 - 2; i++) 102 System.out.print(' '); 103 } 104 System.out.println("\n"+dots + dots); 105 } 106 }
9.3.HTest.java
1 package com.cn.heap; 2 /** 3 * heap類的測試 4 * @author Administrator 5 * 6 */ 7 public class HTest { 8 public static void main(String[] args) { 9 Heap h = new Heap(10); 10 h.insert(10); 11 h.insert(30); 12 h.insert(20); 13 h.insert(18); 14 h.insert(12); 15 h.displayHeap(); 16 h.remove(); 17 h.displayHeap(); 18 } 19 }
10.堆的效率:上述操做的時間複雜度是:O(logn)。
11.堆排序實現思路:使用insert()向堆中插入全部無序的數據項,而後重複使用remove()方法,就能夠按序移除全部數據項,它的效率和快速排序相似,都是O(NlogN),但快排稍微快些,由於堆插入時的向下篩選多出的比較所佔用的時間。
11.1.Node.java
1 package com.cn.heap; 2 /** 3 * 堆的節點類 4 * @author Administrator 5 * 6 */ 7 public class Node { 8 private int iData; 9 public Node(int id){ 10 iData = id; 11 } 12 public int getkey(){ 13 return iData; 14 } 15 public void setkey(int id){ 16 iData = id; 17 } 18 }
11.2.Heap.java
1 package com.cn.heap; 2 /** 3 * 堆的實現類 4 * @author Administrator 5 * 6 */ 7 public class Heap { 8 private Node[] heapArray; 9 private int maxSize; 10 private int currentSize; 11 public Heap(int mx){ 12 maxSize = mx; 13 heapArray = new Node[maxSize]; 14 currentSize = 0; 15 } 16 public boolean isEmpty(){ 17 return currentSize == 0 ; 18 } 19 public boolean insert(int key){ 20 if (currentSize == maxSize) 21 return false; 22 Node thenode = new Node(key); 23 heapArray[currentSize] = thenode; 24 trickleUp(currentSize ++); 25 return true; 26 } 27 public void trickleUp(int index){ 28 int parent = (index - 1) / 2; 29 Node bottom = heapArray[index]; 30 while (index > 0 && heapArray[parent].getkey() < bottom.getkey()){ 31 heapArray[index] = heapArray[parent]; 32 index = parent; 33 parent = (parent - 1) / 2; 34 } 35 heapArray[index] = bottom; 36 } 37 public Node remove(){ 38 Node root = heapArray[0]; 39 heapArray[0] = heapArray[-- currentSize]; 40 trickleDown(0); 41 return root; 42 } 43 public void trickleDown(int index){ 44 int largeChild; 45 Node top = heapArray[index]; 46 while (index < currentSize / 2){ 47 int leftChild = 2 * index + 1; 48 int rightChild = 2 * index + 2; 49 if (rightChild < currentSize && heapArray[leftChild].getkey() < heapArray[rightChild].getkey()) 50 largeChild = rightChild; 51 else 52 largeChild = leftChild; 53 if (top.getkey() >= heapArray[largeChild].getkey()) 54 break; 55 heapArray[index] = heapArray[largeChild]; 56 index = largeChild; 57 } 58 heapArray[index] = top; 59 } 60 public boolean change(int index,int newvalue){ 61 if (index < 0 || index >=currentSize) 62 return false; 63 int oldvalue = heapArray[index].getkey(); 64 heapArray[index].setkey(newvalue); 65 if (oldvalue < newvalue) 66 trickleUp(index); 67 else 68 trickleDown(index); 69 return true; 70 } 71 public void displayHeap(){ 72 System.out.print("heapArray:"); 73 for (int i = 0; i < currentSize; i++) { 74 if (heapArray[i] != null) 75 System.out.print(heapArray[i].getkey()+" "); 76 else 77 System.out.print("--"); 78 } 79 System.out.println(""); 80 int nBlanks = 32; 81 int itemsPerrow = 1; 82 int column = 0; 83 int j = 0; 84 String dots = "........................"; 85 System.out.println(dots + dots); 86 while (currentSize > 0){ 87 if (column == 0) 88 for (int i = 0; i < nBlanks; i++) { 89 System.out.print(" "); 90 } 91 System.out.print(heapArray[j].getkey()); 92 if (++ j == currentSize) 93 break; 94 if (++ column == itemsPerrow){ 95 nBlanks /= 2; 96 itemsPerrow *= 2; 97 column = 0; 98 System.out.println(); 99 } 100 else 101 for (int i = 0; i < nBlanks * 2 - 2; i++) 102 System.out.print(' '); 103 } 104 System.out.println("\n"+dots + dots); 105 } 106 public void displayArray(){ 107 for (int i = 0; i < maxSize; i++) 108 System.out.print(heapArray[i].getkey()+" "); 109 System.out.println(); 110 } 111 public void insertAt(int index,Node newnode){ 112 heapArray[index] = newnode; 113 } 114 public void incrementSize(){ 115 currentSize ++; 116 } 117 }
11.3.HeapSort.java
1 package com.cn.heap; 2 3 import java.util.Scanner; 4 5 /** 6 * 基於堆的排序----堆排序 7 * @author Administrator 8 * 9 */ 10 public class HeapSort { 11 public static void main(String[] args) { 12 int size,j; 13 Scanner in = new Scanner(System.in); 14 System.out.print("Enter number of items: "); 15 size = in.nextInt(); 16 Heap theheap = new Heap(size); 17 for (int i = 0; i < size; i++) { 18 int random = (int)(Math.random()*100); 19 Node node = new Node(random); 20 theheap.insertAt(i, node); 21 theheap.incrementSize(); 22 } 23 System.out.print("random: "); 24 theheap.displayArray(); 25 for (int i = size / 2 - 1; i >= 0; i --) { 26 theheap.trickleDown(i); 27 } 28 System.out.print("heap: "); 29 theheap.displayArray(); 30 theheap.displayHeap(); 31 for (int i = size - 1; i >= 0; i --) { 32 Node node = theheap.remove(); 33 theheap.insertAt(i,node); 34 } 35 System.out.print("sorted: "); 36 theheap.displayArray(); 37 } 38 }