`
java--hhf
  • 浏览: 306082 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

优先级队列(堆实现)

阅读更多

(一)优先级队列定义



(二)方法实现 

获得最大元素方法


去掉最大元素方法



 修改优先级方法


添加节点


 

(三)实现

/**
 * 用堆实现一个优先级队列
 * 主要是添加、修改、删除节点
 * 节点具有唯一性
 * @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)

  • 大小: 24 KB
  • 大小: 1.8 KB
  • 大小: 8 KB
  • 大小: 7.5 KB
  • 大小: 9 KB
  • 大小: 9.4 KB
  • 大小: 5.8 KB
  • 大小: 4 KB
  • 大小: 15.8 KB
  • 大小: 39 KB
0
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics