1. 程式人生 > >(第17講)堆的陣列實現

(第17講)堆的陣列實現

堆:

1、實際是一種完全二叉樹,只有最後一層會不滿,所以用陣列實現,陣列都會填滿,不會有空缺

2、堆的左右子節點都不大於父節點,即父節點大於或者等於其子節點

程式如下:

/**
 * 堆:基於陣列的
 * 堆實際上是一個完全二叉樹,並且其左右子節點都不大於父節點(父節點大於子節點)
 */
package com.twelve;


import java.util.Scanner;


public class HeapApp {


public static void main(String[] args) {
int size = 32;
Heap  heap = new Heap(size);
heap.insert(70);            
heap.insert(40);
heap.insert(50);
heap.insert(20);
heap.insert(60);
heap.insert(100);
heap.insert(80);
heap.insert(30);
heap.insert(10);
heap.insert(90);  heap.display();
heap.insert(53); heap.display();
heap.delete();
heap.display();
     System.out.println("請輸入兩個整數");
     int index = getInt();
     int value = getInt();
     heap.change(index, value);
     heap.display();
}
public static String getString(){
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
return s;
}
public static int getInt(){
String s = getString();
return Integer.parseInt(s);
}
}
//結點類
class Node{
private int data;
public int getData(){
return data;
}
public void setData(int value){
data = value;
}
public Node(int data){
this.data = data;
}
}
//堆類
class Heap{
private Node[] heapArr ;
private int curlen;
private int arrlen;
public Heap(int size){
arrlen = size;
heapArr = new Node[arrlen];
curlen = 0;
}
//增
public void insert(int key){
if(!isFull()){
Node newnode = new Node(key);
heapArr[curlen] = newnode;
trickleUp(curlen);
curlen++;
}

}
//刪:刪除根節點上的,在本案例中是降序堆,所以是刪除優先順序最大的
public void delete(){
heapArr[0] = heapArr[--curlen];
trickleDown(0);
}
//更改優先順序
public void change(int index,int value){
int oldvalue = heapArr[index].getData();
heapArr[index].setData(value);
if(oldvalue<value)
trickleUp(index);
else 
trickleDown(index);
}
//向上篩選
public void trickleUp(int index)
{
int parent = (index-1)/2;
Node temp = heapArr[index];
while(index>0 && heapArr[parent].getData()<temp.getData())
{
heapArr[index] = heapArr[parent];
index = parent;
parent = (parent-1)/2;
}
heapArr[index] = temp;
}
//向下篩選
public void trickleDown(int index){
Node temp = heapArr[index];
while(index < curlen/2){//當這個位置有子節點的時候
int left = index*2+1;
int right = left+1;
int larger = 0;
if(right<curlen && heapArr[left].getData()<heapArr[right].getData())
larger = right;
else
larger = left;
heapArr[index] = heapArr[larger];
index = larger;
}
heapArr[index] = temp;
}
//遍歷
public void display(){
System.out.println("陣列顯示");
for(int i=0;i<arrlen;i++){
if(heapArr[i]!=null){
//因為沒有洞,堆是一顆完全二叉樹,所以不用判斷這個位置上的結點是否有值,直接顯示即可
System.out.print(heapArr[i].getData()+" ");
}else
System.out.print(" ");
}
System.out.println();
String dot = ".......................................";
System.out.println(dot+dot);
int nBlanks = 32;//空格的長度
   int itemsPerRow = 1;//一行
   int column = 0;//一行中的第一個元素
   int j = 0;    //堆中元素的下標        
 //當堆中有元素時
   while(curlen > 0)     
      {
      if(column == 0)                  // 一行中的第一個元素
         for(int k=0; k<nBlanks; k++)  //前面的空白
            System.out.print(' ');  
     System.out.print(heapArr[j].getData());//輸出堆中的元素
      
      if(++j == curlen) //如果堆中元素輸出完畢,結束       
         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(' ');     // 中間的空格
      }//while迴圈結束,即堆中元素輸出完畢  
System.out.println("\n"+dot+dot);
}
//判斷是否為空
public boolean isEmpty(){
return curlen==0;
}
//判斷是否為滿
public boolean isFull(){
return curlen==arrlen;

}

結果是:

 陣列顯示
100 90 80 30 60 50 70 20 10 40                       
..............................................................................
                                100
                90                              80
        30              60              50              70
    20      10      40
..............................................................................
陣列顯示
100 90 80 30 60 50 70 20 10 40 53                      
..............................................................................
                                100
                90                              80
        30              60              50              70
    20      10      40      53
..............................................................................
陣列顯示
90 60 80 30 40 50 70 20 10 53 53                      
..............................................................................
                                90
                60                              80
        30              40              50              70
    20      10      53
..............................................................................
請輸入兩個整數
3
98
陣列顯示
98 90 80 60 40 50 70 20 10 53 53                      
..............................................................................
                                98
                90                              80
        60              40              50              70
    20      10      53
..............................................................................