算法笔记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());
		}
	}

}

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