最小堆的java實現
阿新 • • 發佈:2019-01-29
<pre name="code" class="plain">
//從大牛那裡轉來的最小堆的動態新增與刪除,以後好好看public class Node {/** * 堆結點 * 節點資料型別為:int */private int iDate;public Node(int iDate) {super();this.iDate = iDate;}public int getiDate() {return iDate;}public void setiDate(int iDate) {this.iDate = iDate;}}
public class MinHeap { /** * 最小堆實現 */ private Node[] heapArray; // 堆容器 private int maxSize; //堆最大大小 private int currentSize; //堆當前大小 public MinHeap(int maxSize){ //構造最小堆 this.maxSize=maxSize; heapArray=new Node[maxSize]; currentSize=0; } //自上而下掃描樹,將結點換成兩個子女中較大的哪一個 public void filterDown(int start, int endOfHeap) { int i=start; int j=2*i+1; Node temp = heapArray[i]; while(j<=endOfHeap){//檢查是否到達最後位置 //讓j指向兩子女中的最小點 if(j<endOfHeap && heapArray[j].getiDate()>heapArray[j+1].getiDate()){ j++; } if(temp.getiDate()<=heapArray[i].getiDate()){//小則不作調整 break; }else{//當前結點大,則交換i,j heapArray[i]=heapArray[j]; i=j; j=2*j+1; } } heapArray[i] = temp;//回送 } // 自下而上的調整:從結點start開始到0為止,自下向上比較,如果子女的值小於雙親結點的值則互相交換 public void filterUp(int start) { int j=start; int i=(j-1)/2; Node temp = heapArray[j]; while(j>0){ // 沿雙親結點路徑向上直達根節點 if(heapArray[i].getiDate()<=temp.getiDate()){// 雙親結點值小,不調整 break; }else{ heapArray[j] = heapArray[i]; j = i; i = (i - 1) / 2; } } heapArray[j] = temp; // 回送 } //插入元素,根據當前關鍵字構建結點,從上下掃描成功則插入,並且將堆的大小+1 public boolean insert(int key) throws MinHeapException { boolean bool = true; if (isFull()) { bool = false; throw new MinHeapException("MinHeap is full!"); } else { Node newNode = new Node(key); heapArray[currentSize] = newNode; filterUp(currentSize); currentSize++; } return bool; } //刪除最小元素,先刪除根節點,然後自下向上掃描,重新建立堆結構 public Node removeMin() throws MinHeapException { if (isEmpty()) { throw new MinHeapException("MinHeap is empty!"); } Node root = heapArray[0]; heapArray[0] = heapArray[currentSize - 1]; currentSize--; filterDown(0, currentSize - 1); return root; } /** * 按某種格式輸出堆 */ public void displayHeap() { System.out.print("heapArray: "); for (int i = 0; i < currentSize; i++) { if (heapArray[i] != null) { System.out.print(heapArray[i].getiDate() + " "); } else { System.out.print("-- "); } } System.out.println(); int nBlanks = 32; // heap format int itemsPerRow = 1; int column = 0; int j = 0; // current item String dots = "..............................."; System.out.println(dots + dots); // dotted top line while (currentSize > 0) { // for each heap item if (column == 0) { // first item in row for (int k = 0; k < nBlanks; k++) { // preceding blanks System.out.print(" "); } } System.out.print(heapArray[j].getiDate()); // display item if (++j == currentSize) { // done? break; } if (++column == itemsPerRow) { // end of row? nBlanks /= 2; // half the blanks itemsPerRow *= 2; // twice the items column = 0; // start over on System.out.println(); // next row } else { // next item on row for (int k = 0; k < nBlanks * 2 - 2; k++) { System.out.print(' '); // interim blanks } } } System.out.println("\n" + dots + dots); } public boolean isEmpty() { return currentSize == 0; } public boolean isFull() { return currentSize == maxSize; } public void makeEmpty() { currentSize = 0; } }
public class MinHeapException extends Exception {
/**
*
*/
private static final long serialVersionUID = 1L;
public MinHeapException() {
super("MinHeapException");
}
public MinHeapException(String exMsg) {
super(exMsg);
}
}
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; /** * 最小堆應用測試 */ public class MinHeapApp { /** * @param args * @throws IOException * @throws MinHeapException */ public static void main(String[] args) throws IOException, MinHeapException { int value, value2; MinHeap hp = new MinHeap(31); boolean success; hp.insert(53); hp.insert(17); hp.insert(78); hp.insert(9); hp.insert(45); hp.insert(65); hp.insert(87); hp.insert(23); while (true) { System.out.print("Enter first letter of "); System.out.print("show, insert, remove: "); int choice = getChar(); switch (choice) { case 's': hp.displayHeap(); break; case 'i': System.out.print("Enter value to insert: "); value = getInt(); success = hp.insert(value); if (!success) { System.out.println("Can't insert; heap is full"); } break; case 'r': if (!hp.isEmpty()) { hp.removeMin(); } else { System.out.println("Can't remove; heap is empty"); } break; default: System.out.println("Invalid entry\n"); } } } /** * 獲得控制檯輸入流 * * @return * @throws IOException */ public static String getString() throws IOException { return new BufferedReader(new InputStreamReader(System.in)).readLine(); } /** * 獲得控制檯輸入字元 * * @return * @throws IOException */ public static char getChar() throws IOException { return getString().charAt(0); } /** * 獲得控制檯輸入整型 * * @return * @throws NumberFormatException * @throws IOException */ public static int getInt() throws NumberFormatException, IOException { return Integer.parseInt(getString()); } }