小根堆

public class MinHeap {
	//默认初始化长度
    private static final int DEFAULT_INIYIAL_CAPACITY = 10;
    //堆使用的长度
    private int currentSize;
    //堆最大长度
    private int capacity;
    
    private int [] queue;
    
    
	/**
	 * 无参构造
	 */
	public MinHeap() {
		
		currentSize = 0;
		this.capacity = DEFAULT_INIYIAL_CAPACITY;
		int []queue = new int [DEFAULT_INIYIAL_CAPACITY];
	}
	/**
	 * 有参构造
	 */
    public MinHeap(int capacity) {
    	if (capacity<1||capacity>Integer.MAX_VALUE) {
    		throw new IndexOutOfBoundsException();
    	}
    	currentSize = 0;
		this.capacity = capacity;
		queue = new int [capacity];
    	
    }

    /**
	 * 添加元素
     * @throws Exception 
	 */
    public void add(int val) throws Exception{
    	int top = getTop();
    	//如果使用的长度大于给定的长度抛出异常
    	if(currentSize >=capacity-1) {
    	throw new Exception();
    	//如果为空,直接放入
    	}else if (currentSize == 0) {
    		queue[++currentSize]= val;
    		//不为空就判断他是否大于堆顶点
    	}else{
    	    if(val>top) {
    	    	remove();
    	    	adjustUp(++currentSize,val);
    	    }
    	}
    }
    

	/**
	 * 删除栈顶元素
	 */
	private int  remove() {
		// TODO Auto-generated method stub
		//获得栈顶元素
		int top = getTop();
		//获得数组的最后一个位置的元素
		int q = queue[--currentSize];
		//将第一个和最后一个交换
		queue[0] = q;
		//重新调整
		adjustDown(0,q);
		//将交换后的最后一个制空
		queue[currentSize-1] = -1;
		//返回栈顶元素
		return top;
	}
	/**从上往下调整
	 * @param i
	 * @param q
	 */
	private void adjustDown(int k, int val) {
		// TODO Auto-generated method stub
		//二叉树特性
		int half = currentSize>>>1;
		while(k<half) {
			//左孩子的key
			int leftChild = (k<<1)+1;
			//获得左孩子的值
			int leftChildVal = queue[leftChild];
			//右孩子的key
			int rightChild = leftChild+1;
			//先判断是否存在右孩子,在判断左右孩子的大小,找到最小的那个
			if (rightChild<currentSize&&leftChildVal>queue[rightChild]) {
				leftChildVal = queue[leftChild = rightChild];
			}
			//如果孩子的值大于val,跳出
			if(leftChildVal>val) {
				break;
			}
			//没有找到较小的孩子放到根节点
			queue[k] = queue[leftChild];
			//k往下移
			k = leftChild;
		}
		//把值放在k号位置
		queue[k] =  val;
	}
	/*
	 * 打印堆
	 */
	 public void show() {
		 for (int i =0;i<currentSize;i++){
			 System.out.println(queue[i]);
		 }
		 System.out.println();
	 }
	/**
	 * @param i
	 * @param q
	 */
	private void adjustUp(int k, int val) {
		// TODO Auto-generated method stub
		while(k>0) {
			//获得父节点
			int parent = (k-1)>>>1;
			int p =queue[parent];
			//如果要调整的值大于父节点的值,符合小根堆,跳出
			if(val>=p) {
				break;
			}
			//如果父节点大于要调整的值,两值交换位置
			queue[k] = p;
			k = parent;
		}
		queue[k] = val;
	}
	/**
	 * @return
	 */
	private int getTop() {
		// TODO Auto-generated method stub
		return queue[0];
	}


猜你喜欢

转载自blog.csdn.net/qq_41974391/article/details/80964332