算法筆記7:TopK問題——優先序列(基於二叉堆)

基於二叉堆的優先序列

/**
 * 基於二叉堆的優先序列
 * @author XY
 *
 */
@SuppressWarnings("unchecked")
public class Priorityheap<Key extends Comparable<Key>> {
	private final int len_default=8;
	private Key[] pq;
	private int size;
	private int len;
	
	public Priorityheap(){
		this.len=len_default+1;
		pq=(Key[])new Comparable[len];
		this.size=0;
	}
	public Priorityheap(int len){
		this.len=len+1;
		pq=(Key[])new Comparable[len];
		this.size=0;
	}
	public Priorityheap(Key[] key){
		this.len=key.length+1;
		pq=(Key[])new Comparable[len];
		this.size=0;
		for (int i = 0; i < key.length; i++) {
			insert(key[i]);
		}
	}
	public void insert(Key key){
		pq[++size]=key;//數據是從1開始存儲的,這是因爲這種方式正好能給二叉堆帶來遍歷方便。
		swim(size);
		check();//改變數組大小
	}
	
	public Key max(){
		return pq[1];
	}
	public Key delMax(){
		Key temp=pq[1];
		pq[1]=pq[size];
		pq[size--]=null;
		sink(1);
		check();
		return temp;
	}
	public void swim(int k){//上浮,檢查是否比父節點大,使其到達合適的二叉樹層級,恢復堆有序		
		while (k/2 >0 && less(k/2,k)) {
			exchange(k, k/2);
			k/=2;
		}
	}
	public void sink(int k){//下沉,刪掉根節點後將末位放置在根節點的位置上然後下沉恢復堆有序
		while(k*2<=size){
			int j=k*2;
			if(j+1<=size && less(j, j+1)){ j++;}	//這裏的邊界應該是有子節點(1或2個)都應該進行下沉
			if(less(k, j)) {exchange(k, j);k=j;}
			else break;
		}
	}
	public boolean isEmpty(){
		return this.size==0;
	}
	public int size(){
		return this.size;
	}
	public void check(){
		if(size==len-1){
			len*=2;
			Key[] temp=pq;
			pq=(Key[])new Comparable[len];
			for (int i = 1; i < temp.length; i++) {
				pq[i]=temp[i];
			}
			temp=null;
		}else if (size<len/4) {
			len/=2;
			Key[] temp=pq;
			pq=(Key[])new Comparable[len];
			for (int i = 1; i < pq.length; i++) {
				pq[i]=temp[i];
			}
			temp=null;
		}
	}
	public void exchange(int a,int b){
		Key temp=pq[a];
		pq[a]=pq[b];
		pq[b]=temp;
	}
	public boolean less(int a,int  b){
		return pq[a].compareTo(pq[b])<0;
	}
	public static void main(String[] args) {
		Integer[] v={5,2,3,6};
		Integer[] w={2,4,7,9};
		Priorityheap<Integer> a=new Priorityheap<Integer>(v);
		a.insert(w[0]);
		a.insert(w[1]);
		a.insert(w[2]);
		a.insert(w[3]);
//		System.out.println(a.size());
		a.insert(w[0]);
		while(!a.isEmpty()){
			System.out.println(a.delMax());
		}
	}

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章