利用二叉堆实现最小优先队列

利用二叉堆实现最小优先队列

package 第二章数据结构基础;

import java.util.Arrays;

public class 二叉堆和优先队列 {
	public static void main(String[] args) {
		YouXianQueue queue = new YouXianQueue(5);
		queue.enQueue(3);
		queue.enQueue(5);
		queue.enQueue(1);
		queue.enQueue(2);
		queue.enQueue(12);
		queue.enQueue(115);
		queue.enQueue(22);
		System.out.println(queue.toString());
		System.out.println("出队"+queue.deQueue());
		System.out.println(queue.toString());
		System.out.println("出队"+queue.deQueue());
		System.out.println(queue.toString());
		System.out.println("出队"+queue.deQueue());
		System.out.println(queue.toString());
		System.out.println("出队"+queue.deQueue());
		System.out.println(queue.toString());
		System.out.println("出队"+queue.deQueue());
		System.out.println(queue.toString());
		System.out.println("出队"+queue.deQueue());
		System.out.println(queue.toString());
		
		
	} 
}
/*
 * 优先队列类,继承了二叉堆类,以便使用其方法
 */
class YouXianQueue extends ErChaDui{
	private int[] array;
	private int size;
	YouXianQueue(int capacity){
		this.array = new int[capacity];
		this.size = 0;
	}
	public String toString() {
		return Arrays.toString(Arrays.copyOf(array,size));
	}
	/*
	 * 入队
	 * @param element 入队元素
	 * 方法:1、加入队尾,2、上浮
	 */
	//程序中使用throw抛出运行时异常,可以使用throws或try catch语句捕获,也可以不捕获
	//只有使用throw抛出checked异常时,才必须对其进行捕获
	void enQueue(int element){
		if(size>=array.length) {
			reSize();
		}
		array[size++] = element;
		upAdjust(array,size);
	}
	/*
	 * 出队
	 * 方法:1、删除队头元素,将队尾元素放到队头,2、将队头下沉
	 */
	//程序中使用throw抛出运行时异常,可以使用throws或try catch语句捕获,也可以不捕获
	//只有使用throw抛出checked异常时,才必须对其进行捕获
	int deQueue(){
		if(size<=0) {
			throw new NullPointerException("队列已空");
		}
		int head = array[0];
		array[0] = array[--size];
		downAdjust(array, 0,size);
		return head;
	}
	private void reSize() {
		int newSize = 2*this.array.length;
		this.array = Arrays.copyOf(array, newSize);
	}
}
class ErChaDui{
	/*
	 * 上浮调整
	 * 将二叉堆队尾元素上浮到适当位置
	 */
	static void upAdjust(int[] array,int length) {
		if(array==null) {
			return;
		}
		int childIndex = length-1;
		int parentIndex = (childIndex-1)/2;
		int temp = array[childIndex];
		while(childIndex>0 && array[childIndex]<array[parentIndex]) {
			array[childIndex] = array[parentIndex];
			childIndex = parentIndex;
			parentIndex = (parentIndex-1)/2;
			
		}
		array[childIndex] = temp;
	} 
	/*
	 * 下沉调整
	 * 将二叉堆队列中插入的元素下沉到适当位置
	 * @param array 待调整的堆
	 * @param index 需要下沉的结点
	 * @param length 堆的有效长度
	 */
	static void downAdjust(int[] array,int index,int length) {
		if(array==null || index<0 || index >=length) {
			return;
		}
		int temp = array[index];
		int childIndex = index*2+1;
		while(childIndex<length) {
			//防止出现将结点下沉到了左孩子,但是右孩子却小于结点值
			if(childIndex+1<length && array[childIndex+1]<array[childIndex]) {
				childIndex++;
			}
			if(temp<=array[childIndex]) {
				break;
			}
			array[index] = array[childIndex];
			index = childIndex;
			childIndex = childIndex*2+1;
		}
		array[index] = temp;	
	}
	/*
	 * 构建二叉堆
	 * @param array 待构建的原堆
	 */
	private static void buildHeap(int[] array) {
		for(int i = (array.length-2)/2; i>=0; i--) {
			downAdjust(array, i,array.length);
		}
	}
	void testMain() {
		int[] array = new int[] {2,3,1,56,7,4,23,12,0};
		upAdjust(array,array.length);
		System.out.println(Arrays.toString(array));
		downAdjust(array, 1,array.length);
		System.out.println(Arrays.toString(array));
		
		buildHeap(array);
		System.out.println(Arrays.toString(array));
		
	}
}

你可能感兴趣的:(利用二叉堆实现最小优先队列)