优先级队列(堆实现)

(一)优先级队列定义



(二)方法实现 

获得最大元素方法


去掉最大元素方法



 修改优先级方法


添加节点


 

(三)实现

/**
 * 用堆实现一个优先级队列
 * 主要是添加、修改、删除节点
 * 节点具有唯一性
 * @author HHF
 * 2014年11月28日
 */
public class PriorityQueue {

	public static int HEAPSIZE;
	public static void main(String[] args) {
		int[] array = Common.random(0,100,10);
		HEAPSIZE = array.length;
		build(array);//建一个极大堆
		System.out.println("原始数据:");
		Common.print(array);
	
		//获得最大值
		System.out.println("优先级最高的节点:"+maximum(array));
		
		//获得并删除最大值
		System.out.println("将要被删除的优先级最高的节点:"+extractMax(array));
		System.out.println("删除后的数据:");
		Common.print(array);
		
		//修改优先级
		increaseKey(array, 5, 100);
		System.out.println("修改后的数据:");
		Common.print(array);
		
		//添加节点
		insert(array, 101);
		System.out.println("插入后的数据:");
		Common.print(array);
		
		//删除节点
		System.out.println("删除的数据:"+delete(array, 1));
		System.out.println("删除后的数据:");
		Common.print(array);
	}
	
	/**
	 * 返回优先队列中优先级最高的节点
	 * @param array
	 * @return
	 */
	public static int maximum(int[] array){
		return array[0];
	}
	
	/**
	 * 去掉并返回优先级队列中优先级最高的节点
	 * @param array
	 * @return
	 */
	public static int extractMax(int[] array){
		if(HEAPSIZE < 1){
			(new Exception("队列内无元素    ")).printStackTrace();
			return 0;
		}
		//获得最优节点
		int max = array[0];
		//删除最优节点
		array[0] = array[--HEAPSIZE];
		//整理堆
		heapify(array, 0);
		//返回最优节点值
		return max;
	}
	
	/**
	 * 往优先队列中插入节点
	 * 记得要去重
	 * @param array
	 * @param x
	 */
	public static void insert(int[] array, int x){
		array[HEAPSIZE++] = x-1;//加一个元素
		increaseKey(array, HEAPSIZE-1, x);
	}
	
	/**
	 * 将优先级为x的节点优先级修改为k
	 * @param array
	 * @param i被修改值下标
	 * @param k
	 */
	public static void increaseKey(int[] array, int i, int k){
		if(HEAPSIZE <= i){
			(new Exception("修改优先级节点下标有误  ")).printStackTrace();
			return;
		}
		if(k <= array[i]){
			(new Exception("新节点的优先级被改低了  ")).printStackTrace();
			return;
		}
		//优先级被修改了
		array[i] = k;
		//整理队列
		int parent = (i-1)/2; //父节点下标
		while(parent>-1 && array[parent]<array[i]){//到了必要交换子父节点的时候了
			Common.swap(array, parent, i);
			i = parent;
			parent = (i-1)/2;
		}
	}
	
	/**
	 * 将下标为i的节点删除 并返回其值
	 * @param array
	 * @param i
	 */
	public static int delete(int[] array, int i){
		if(HEAPSIZE <= i){
			(new Exception("删除节点下标有误  ")).printStackTrace();
			return 0;
		}
		//优先级被修改了
		int result = array[i];
		//整理队列
		array[i] = -1;
		heapify(array, i);
		HEAPSIZE--;
		return result;
	}
	
	/**
	 * 将array变成一个极大堆
	 * @param array 堆
	 */
	public static void build(int[] array){
		int size = array.length;
		for(int i=size/2-1; i>=0; i--){
			heapify(array, i);
		}
	}
	
	/**
	 * 前提是i的左右孩子子树均已经为正常极大堆
	 * 将i调整为正确位置
	 * @param array
	 * @param i 下标
	 */
	public static void heapify(int[] array, int i){
		int left = 2*i+1;//左孩子下标
		int right = left+1;//右孩子下标
		int large = 0;
		//选出left right 和  i 三个下标对应的最大值 记其下标为large 
		if(left<HEAPSIZE  && array[left] > array[i]){
			large = left;
		}else{
			large = i;
		}
		if(right<HEAPSIZE && array[right] > array[large]){
			large = right;
		}
		//准备发生交换 和 递推下一轮
		if(large != i){
			Common.swap(array, large, i);
			heapify(array, large);//此时的i所对应的值 已经 下移一层到了large
		}
	}
}

 (ps:附件内附上工具类Common.zip)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值