1. 程式人生 > >堆(插入刪除)

堆(插入刪除)

bool 裏的 輸入 default main system heap move parent

用堆實現優先級隊列,插入和刪除都很快o(logN)
編程語言中的內存堆與這裏的數據結構是不一樣的
堆:一種樹(特殊的二叉樹)
特點:它是完全二叉樹,除了樹的最後一層節點不需要是滿,其他的每一層從左到右都完全是滿的。
它常常是用一個數組實現
堆中的每一個節點都滿足堆的條件,父節點的關鍵字要大於所有子節點。
堆是弱序(遍歷不適合)
插入:獲取一個節點,放入完全二叉樹中。與其父節點作比較,替換(完成父節點的關鍵字要大於子節點)
刪除:刪除頂端節點,將最後一個葉子節點賦值為頂點節點。然後移動 完成父節點的關鍵字要大於子節點。
改變節點優先級:將該節點的值更換。然後將它放在合適的位置(完成父節點的關鍵字要大於子節點)
(父節點的關鍵字要大於所有子節點,即三個點之間選取最大的與臨時父節點替換)

public class Node {
    private int iData;//既是關鍵字,又是數值
    public Node(int key) {//初始化
        iData=key;
        
    }
    public int getKey() {//訪問關鍵字
        return iData;
    }
    public void setKey(int id) {//改變關鍵字
        iData=id;
    }

}
//建立堆
public class Heap {
    private Node[] heapArray;//存儲節點的數組
private int maxSize;//總大小 private int currentSize;//當前堆的大小 public Heap(int mx) { maxSize=mx;//初始化總大小 currentSize=0;//初始化當前數據大小0 heapArray=new Node[maxSize]; } //判斷是否為空 public boolean isEmpty() { return currentSize==0; } //增加(判斷為滿,則不能新增) public
boolean insert(int key) { if(currentSize==maxSize) return false; Node newNode=new Node(key);//建立key節點 heapArray[currentSize]=newNode;//將key節點插入數組的最末 //(向上調整)完成堆的規則(父節點大於子節點) trickleUP(currentSize); currentSize++;//增加成功,數量加1 return true; } //向上調整(只需要跟父節點做比較就行了,因為開始的時候父節點就是最大值) public void trickleUP(int index) { //取父節點 int parent=(index-1)/2; //比較,交換 Node bottom=heapArray[index]; while(index>0 && heapArray[parent].getKey()<bottom.getKey()) {//尋找需要替換的位置 heapArray[index]=heapArray[parent]; index=parent; parent=(parent-1)/2; } heapArray[index]=bottom; } //刪除(刪除根,將最後一個數據項移到根上,然後做調整) public Node remove() { Node root=heapArray[0]; heapArray[0]=heapArray[--currentSize];//將最後一個數據項移到根上 //向下調整 trickleDown(0); return root; } //向下調整 public void trickleDown(int index) { int largeChild;//記錄大的子節點 Node top=heapArray[index]; while(index<currentSize/2) {//指針到了最後一層才停止循環 int leftChild=2*index+1;//左子節點 int rightChile=leftChild+1; //右子節點 if(rightChile<currentSize && heapArray[leftChild].getKey()<heapArray[rightChile].getKey())//有右子節點 largeChild=rightChile; else largeChild=leftChild; if(top.getKey()>=heapArray[largeChild].getKey()) break; heapArray[index]=heapArray[largeChild];//將大的關鍵字調整 index=largeChild; } //最後定位Node top=heapArray[index] heapArray[index]=top; } //更改關鍵字 public boolean change(int index, int newValue) { if(index<0 || index >=currentSize) return false;//非正常索引 int oldValue=heapArray[index].getKey(); heapArray[index].setKey(newValue);//改變數據項 //如果新的數據項大於舊的數據項,就向上調整。如果小於舊的數據項,就向下調整 if(oldValue<newValue) { trickleUP(index); }else trickleDown(index); return true; } //顯示堆 public void displayHeap() { //以數組的方式 System.out.println("堆數組"); for(int m=0;m<currentSize;m++) if(heapArray[m]!=null) System.out.print(heapArray[m].getKey()+" "); else System.out.print("-- "); System.out.println(); //以樹狀的形式 int nBlanks=32;//控制空格 int itemsPerRow=1;//當前層的個數 int column=0;//當前層的數量 int j=0; String dots="..............................."; System.out.println(dots+dots); while(currentSize>0) { if(column==0) { for(int k=0;k<nBlanks;k++) System.out.print(‘ ‘); } System.out.print(heapArray[j].getKey()); if(++j==currentSize)//全部打印完成 break; if(++column==itemsPerRow) {//當前層打印完 nBlanks/=2; itemsPerRow*=2; column=0; System.out.println(); }else for(int k=0;k<nBlanks*2-2;k++) System.out.print(‘ ‘); } System.out.println("\n"+dots+dots); } }
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Test {
    public static void main(String[] agrs) throws IOException{
        int value,value2;
        Heap theHeap =new Heap(31);
        boolean success;
        theHeap.insert(70);
        theHeap.insert(40);
        theHeap.insert(50);
        theHeap.insert(20);
        theHeap.insert(60);
        theHeap.insert(100);
        theHeap.insert(80);
        theHeap.insert(30);
        theHeap.insert(10);
        theHeap.insert(90);
        while(true) {
            System.out.println("Enter first letter of show ,insert,remove,change:");
            int choice=getChar();
            switch(choice){
                case ‘s‘:
                    theHeap.displayHeap();
                    break;
                case ‘i‘:
                    System.out.print("enter value");
                    value=getInt();
                    success=theHeap.insert(value);
                    if(!success)
                        System.out.println("man le");
                    break;
                case ‘r‘:
                    if(!theHeap.isEmpty())
                        theHeap.remove();
                    else
                        System.out.println("不能刪除");
                    break;
                case ‘c‘:
                    System.out.println("輸入要改變的索引");
                    value=getInt();
                    System.out.println("輸入要改變的值");
                    value2=getInt();
                    success=theHeap.change(value, value2);
                    if(!success)
                        System.out.println("無效的索引");
                    break;
                default :
                        System.out.println("無效的輸入");
                    
            }
                    
        }
        
    }
    public static String getString() throws IOException{
        InputStreamReader isr=new InputStreamReader(System.in);
        BufferedReader br=new BufferedReader(isr);
        return br.readLine();
    }
    public static char getChar() throws IOException{
        return getString().charAt(0);
    }
    public static int getInt() throws IOException{
        return Integer.parseInt(getString());
    }

}

堆(插入刪除)