java數據結構----堆


1.堆:堆是一種樹,由它實現的優先級隊列的插入和刪除的時間復雜度都是O(logn),用堆實現的優先級隊列雖然和數組實現相比較刪除慢了些,但插入的時間快的多了。當速度很重要且有很多插入操作時,可以選擇堆來實現優先級隊列。
2.java的堆和數據結構堆:java的堆是程序員用new能得到的計算機內存的可用部分。而數據結構的堆是一種特殊的二叉樹。
3.堆是具有如下特點的二叉樹:
  3.1.它是完全二叉樹,也就是說除了樹的最后一層節點不需要是滿的,其他的每一層從左到右都必須是滿的。

    3.1.1.完全二叉樹圖解:

 

  3.2.它常常用數組實現。

    3.2.1.數組和堆的對應關系示意圖:

  3.3.堆中每一個節點都滿足堆的條件,也就是說每一個關鍵字的值都大於或等於這個節點的子節點的關鍵字值。
  堆是完全二叉樹的事實說明了表示堆的數組中沒有空項,即從0-->n-1的每個數據單元都有數據項。
4.堆在存儲器中的表示是數組,堆只是一個概念上的表示。

5.堆的弱序:堆和二叉搜索樹相比是弱序的,在二叉搜索樹中,當前節點的值總是比左子節點的值大,卻比它的右子節點的值小,因此按序遍歷相對容易。而堆的組織規則弱,它只要求從根到葉子節點的每一條路徑,節點都是按降序排列的。同一節點的左右子節點都沒有規律。因此,堆不支持按序遍歷,也不能在堆上便利的查找指定關鍵字,因為在查找的過程中,沒有足夠的信息決定選擇通過節點的兩個那一個走向下一層。它也不能在少於O(logn)的時間內刪除一個指定的節點,因為沒有辦法找到這個節點。因此,堆的這種近乎無序的規則似乎毫無用處,不過對於快速移除最大節點的操作,以及快速插入新節點的操作,這種順序已經足夠了。這些操作是使用堆作為優先級隊列所需要的全部操作。

6.移除操作:移除是指刪掉關鍵字值最大的節點,即根節點。移除思路如下:

  6.1.移走根,

  6.2.把左后一個節點移到根的位置,

  6.3.一直向下篩選這個節點,知道它在一個大於它的節點之下,小於它的節點之上為止。

  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 }
View Code

  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 }
View Code

  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 }
View Code

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 }
View Code

  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 }
View Code

  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 }
View Code

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM