• 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()+"	");
    		}
    	}    
    

    结果:

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

  • 相关阅读:
    iOS开发之MapKit
    iOS开发之代码截图
    iOS开发之CoreLocation(二)
    iOS开发之CoreLocation(一)
    iOS开发之静态库.a的制作
    iOS开发之通讯录 AddressBook
    iOS开发之ARC MRC混编
    iOS开发之蓝牙(一)GameKit
    java学习笔记之转换流
    iOS开发之蓝牙(二)CoreBluetooth
  • 原文地址:https://www.cnblogs.com/kakaxisir/p/4316693.html
Copyright © 2020-2023  润新知