My集合框架第五弹 最小堆

二叉堆(以最小堆为例),其具有结构性质和堆序性质
结构性质: 堆是一棵完全的二叉树,一颗高为h的完全二叉树有2^h到2^h-1个节点,高度为log N
            而且该结构可以很容易的使用数组来表示:对于数组中任一位置i上的元素,其左儿子在位置2i上,右儿子在2i+1,其父节点在[x/2]处
堆序性质:在一个堆中,对于每一个节点X,X的父亲中的关键字小于或等于X中的关键字
          也就是说:最小元总可以在根处找到

主要的操作为插入和删除:

以数组存储为例,算法在代码中体现:

     /**
	 * 向堆中插入元素x,
	 * 利用堆的性质,在一个堆中,对于每一个节点X,X的父亲中的关键字都小于或者等于X中的关键字,
	 * ps根节点除外(根节点没有父节点),时间复杂度为logN
	 * step1:如果堆没有满,在完全二叉树的下一个位置插入一个空穴
	 * step2:判断空穴是否存在父节点,如果不存在,直接插入;否则,step3;
	 * step3:(x.value>=[x/2].value)?step4:step5; 
	 * step4:将X直接放在该空穴,return
	 * step5:将父节点的值移入空穴中,空穴就朝着根的方向上前进,回到step2;
	 * @param x
	 */
	public void insert(Comparable x){
		if(cursize == array.length-1){
			//堆已经满了,需要重新调整
			rebuild();
		}
		if(cursize==0){
			//没有父节点
			array[1] = x;
			cursize++;
		}else{
			int temp = ++cursize;
			while(temp>1 && x.compareTo(array[temp/2])<0){
				//父节点下移
				array[temp] =array[temp/2];
				temp/=2;
			}
			//空穴插入
			array[temp] = x;
		}
	}

 删除操作:

        /**
	 * 删除堆中的最小元素并返回,方式与插入向反,时间复杂度为logN
	 * step1:将根节点出视为空穴X
	 * step2:if(空穴X的左右子树都存在) step3;else if(空穴只存在左子树) step4 ;else step5
	 * step3:if(空穴的X的左子树2X>X的右子树2X+1) 空穴<-->右子树;else 空穴<-->左子树;finally 继续step2
	 * step4:空穴和左子树交换,空穴已就位,且满足完全二叉树的要求
	 * step5:空穴和最后一个元素交换位置
	 * @return
	 */
	public Comparable deleteMin(){
		if(isEmpty())
			return null;
		Comparable min = array[1];
		int temp = 1;
		while(2*temp<=cursize){
			if(2*temp+1<=cursize){
				//左右子树都存在
				if(array[2*temp].compareTo(array[2*temp+1])>0){
					array[temp] = array[2*temp+1];
					temp = 2*temp+1;
				}else{
					array[temp] = array[2*temp];
					temp = 2*temp;
				}
			}else{
				//只存在左子树
				array[temp] = array[2*temp];
				temp = 2*temp;
			}
		}
		array[temp] = array[cursize--];
		return min;
	}        

 测试代码:

        @Test
	public void test() {
		BinaryHeap heap = new BinaryHeap();
		for(int i = 19;i>1;i--){
			heap.insert(i);
//			heap.printHeap();
		}
		while(!heap.isEmpty()){
			System.out.print(heap.deleteMin()+"	");
		}
	}    

结果:

好饿啊。。。。。。。。。。。。。。

原文地址:https://www.cnblogs.com/kakaxisir/p/4316693.html