优先队列的实现(最小堆)

使用最小堆实现优先队列

定义上浮函数和下浮函数,对每一次加入的新节点,重新维护最小堆

代码:

public class PriorityMinQueue {
	private int[] arr;
	private int size;

	/**
	 * 返回优先队列的大小
	 *
	 * @return
	 */
	public int Size() {
		return size;
	}

	public PriorityMinQueue() {
		this(20);
	}

	/**
	 * 初始化优先队列
	 *
	 * @param capacity
	 */
	public PriorityMinQueue(int capacity) {
		if (capacity <= 0) {
			capacity = 30;
		} else {
			this.arr = new int[capacity];
			this.size = 1;
		}
	}

	/**
	 * 上浮
	 *
	 * @param i
	 * @param key
	 */
	public void upFloat(int i) {
		while (i > 1) {
			int parent = i / 2;
			if (this.arr[i] >= this.arr[parent]) {
				break;
			}
			swap(i, parent);
			i = parent;
		}
	}

	/**
	 * 下浮操作
	 *
	 * @param i
	 */
	public void downFloat(int i) {
		while (2 * i <= this.size - 1) {
			int child = 2 * i;
			if (child < this.size - 1 && this.arr[child] > this.arr[child + 1]) {
				child++;
			}

			if (this.arr[i] <= this.arr[child]) {
				break;
			}

			swap(i, child);
			i = child;
		}
	}

	/**
	 * 交换两个数
	 *
	 * @param i
	 * @param parent
	 */
	private void swap(int i, int parent) {
		int tmp = this.arr[parent];
		this.arr[parent] = this.arr[i];
		this.arr[i] = tmp;
	}

	/**
	 * 返回堆中的最大值
	 * @return
	 */
	public int Max() {
		return this.arr[0];
	}

	/**
	 * 向优先队列中添加一个元素
	 * @param value
	 */
	public void add(int value) {
		resize();
		this.arr[size++] = value;
		upFloat(size-1);
//
//		for(int i=1;i<size;i++) {
//			System.out.print(arr[i]+" ");
//		}
//		System.out.println();
//		System.out.println("*********************************");
	}

	/**
	 * 重新调整列表容量
	 */
	private void resize() {
		if(size == this.arr.length) {
			System.out.println("正在扩容");
			int []tmparr = new int[arr.length*2];
			for(int i=0;i<size;i++) {
				tmparr[i] = arr[i];
			}
			arr = tmparr;
		}
	}

	/**
	 * 将优先队列中的最大值弹出
	 */
	public int pop() {
		int t = this.arr[1];
		this.arr[1] = this.arr[--size];
		downFloat(1);
		return t;
	}

	/**
	 * 判断优先队列是否为空
	 * @return
	 */
	public boolean isEmpty() {
		if(size==1) {
			return true;
		}else {
			return false;
		}
	}

	/**
	 * 返回队列头
	 * @return
	 */
	public int front() {
		return this.arr[0];
	}

	public static void main(String[] args) {
		PriorityMinQueue minQueue = new PriorityMinQueue();
		for(int i=100;i>0;i--) {
			minQueue.add(i);
		}

		while(!minQueue.isEmpty()) {
			System.out.println(minQueue.pop());
		}
	}
}

  

原文地址:https://www.cnblogs.com/PoorGuy/p/10520880.html

时间: 2024-10-30 02:47:45

优先队列的实现(最小堆)的相关文章

Black Box--[优先队列 、最大堆最小堆的应用]

Description Our Black Box represents a primitive database. It can save an integer array and has a special i variable. At the initial moment Black Box is empty and i equals 0. This Black Box processes a sequence of commands (transactions). There are t

优先队列及最小堆最大堆

为什么优先队列里默认是堆(heap)实现,默认是优先级高的出队,定义结构体重载函数为什么要按照从小到大排序?原来是自己对优先队列还不太了解: 1 堆 1.1 简介 n个关键字序列Kl,K2,-,Kn称为(Heap),当且仅当该序列满足如下性质(简称为堆性质): (1)ki<=k(2i)且ki<=k(2i+1)(1≤i≤ n),当然,这是小根堆,大根堆则换成>=号.//k(i)相当于二叉树的非叶结点,K(2i)则是左孩子,k(2i+1)是右孩子 若将此序列所存储的向量R[1..n]看做是一

hdu 4006 The kth great number (优先队列+STB+最小堆)

The kth great number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others) Total Submission(s): 6637    Accepted Submission(s): 2671 Problem Description Xiao Ming and Xiao Bao are playing a simple Numbers game. In a roun

最小堆(优先队列)基本概念,即一个完整建立,插入,删除代码

堆(优先队列)priority queue特殊的队列,取出元素的顺序是依照元素的优先权(关键字)大小,而出元素进入队列的先后顺序操作:查找最大值(最小值),删除(最大值) 数组:链表:有序数组:有序链表: 采用二叉搜索树? NO 采用完全二叉树 YES堆的连个特性结构性:用数组表示的完全二叉树:有序性:任一结点的关键字是其字树所有结点的最大值(或最小值) 最大堆(MaxHeap)也称大顶堆:最大值 最小堆(MinHeap)也称"小顶堆":最小值 从根节点到任意结点路径上结点序列的有序性

POJ 3784 Running Median (最大最小堆)

最大最小堆动态求中位数 题意:输入M个数,当已输入的个数为奇数个时输出此时的中位数. 一共有M/2+1个中位数要输出,每一行10个. 分析: 用两个优先队列来模拟最大最小堆.中位数是x,就是有一半数比x小,一半数比x大. 刚好符合堆的特点. 用一个从大到小排序的优先队列q1来模拟小于x的数. 从小到大排序的优先队列q2来模拟大于x的数. 动态维护两个优先队列的元素个数.q1.size()=q2.size() 输入的数为偶数个时, q1.size()=q2.size()+1 输入的数为奇数个时.

通用的最小堆(最大堆)D-ary Heap

听说有一种最小(大)堆,不限于是完全二叉树,而是完全D叉树,名为D-ary Heap(http://en.wikipedia.org/wiki/D-ary_heap).D可以是1,2,3,4,100,对于优先队列该有的功能都没有问题. 动手写一个D-ary Heap,应该不难.简单起见,不考虑像STL一样通过template传入Comp类,下面的实现要求T类型重载了operator <和operator >. template<class T> class DaryHeap { s

优先队列及其基本操作的堆实现

用代码说话 /* 本代码实现优先队列:分为最大优秀队列和最小优先队列 优先队列用于维护一组元素构成的集合S的数据结构,其中的 每一个元素都有一个相关的值,称为关键字. 一个最大优先队列支持以下操作: insert(S,x)向S中插入元素x; maximum(S)返回S中的最大键值元素; extract-max(S)去掉并且返回S中的最大键值元素; increase-key(S,x,k)将元素x的关键字增加到k,假设k要不小于x的原关键字 一个最小优先队列支持以下操作: insert(S,x)向S

最小堆的维护,POJ(2051)

题目链接:http://poj.org/problem?id=2051 ///维持最小堆(优先队列)POJ2051 #include <iostream> #include <string> using namespace std; struct Node { int Now; ///出堆的时间 int id; int p; ///时间间隔 }; Node node [3001]; int K; ///输出个数 void down (Node H[],int s,int m) {

优先队列之二叉堆与d-堆

二叉堆简介 平时所说的堆,若没加任何修饰,一般就是指二叉堆.同二叉树一样,堆也有两个性质,即结构性和堆序性.正如AVL树一样,对堆的以此操作可能破坏者两个性质中的一个,因此,堆的操作必须要到堆的所有性质都被满足时才能终止. 结构性质 堆是一棵完全填满的二叉树,因为完全二叉树很有规律,所以它可以用一个数组表示而不需要指针.如下图所示,图2中的数组对应图1中的堆.                   图1:二叉堆