数据结构-堆实现优先队列(java)

队列的特点是先进先出。通常都把队列比喻成排队买东西,大家都很守秩序,先排队的人就先买东西。但是优先队列有所不同,它不遵循先进先出的规则,而是根据队列中元素的优先权,优先权最大的先被取出。这就很像堆的特征:总是移除优先级最高的根节点。

重点:优先级队列,是要看优先级的,谁的优先级更高,谁就先得到权限。不分排队的顺序!

上篇文章解释了堆的概念实现,现在用堆实现优先队列:

//最大堆
import java.util.ArrayList;
public class Heap<E extends Comparable>{
	private ArrayList<E> list=new ArrayList<E>();//用数组实现堆

    public Heap(){}
    public Heap(E[] objects){
    	for(int i=0;i<objects.length;i++){
    		add(objects[i]);
    	}
    }

    public void add(E newObject){//添加一个元素
    	list.add(newObject);
    	int currentIndex=list.size()-1;

    	while(currentIndex>0){
    		int parentIndex=(currentIndex-1)/2;//找到该结点的父结点
    		if(list.get(currentIndex).compareTo(list.get(parentIndex))>0){//与父节点比较
    			//如果当前结点的值大于父结点就交换位置
    			E temp=list.get(currentIndex);
    			list.set(currentIndex, list.get(parentIndex));
    			list.set(parentIndex, temp);
    		}
    		else
    			break;
    		currentIndex=parentIndex;
    	}
    }

    public E remove(){//删除并返回根结点,堆的特点是移除了根结点后还是堆
    	if(list.size()==0) return null;

    	E removeObject=list.get(0);
    	list.set(0, list.get(list.size()-1));//把最后一个结点放在根结点的位置
    	list.remove(list.size()-1);

    	int currentIndex=0;
    	while(currentIndex<list.size()){
    		int leftChildIndex=2*currentIndex+1;
    		int rightChildIndex=2*currentIndex+2;//左右孩子结点的坐标

    		if(leftChildIndex>=list.size())break;
    		//比较左右孩子的值,使maxIndex指向值大的结点
    		 int maxIndex=leftChildIndex;
    		 if(rightChildIndex<list.size()){
    			 if(list.get(maxIndex).compareTo(list.get(rightChildIndex))<0){
    				 maxIndex=rightChildIndex;
    			 }
    		 }
    		 //如果当前结点的值小于其左右孩子中的大的值,就交换两个结点
    		 if(list.get(currentIndex).compareTo(list.get(maxIndex))<0){
    	          E temp=list.get(maxIndex);
    	          list.set(maxIndex, list.get(currentIndex));
    	          list.set(currentIndex, temp);
    	          currentIndex=maxIndex;
    	    	}
    		 else
    			 break;
    	}

    	return removeObject;   	

    }

    public int getSize(){
    	return list.size();
    }

}

MyPriorityQueue.java

public class MyPriorityQueue<E extends Comparable> {
       private Heap<E> heap=new Heap<E>();//用堆实现优先队列
     //入队列
       public void enqueue(E e){
       	heap.add(e); //这个add以后,堆会自己调整成一个新堆
       }
       //出队列
       public E dequeue(){
       	return heap.remove();//这移除出之后,堆会自己调整,还是一个新堆
       }
       public int getSize(){
       	return heap.getSize();
       }

}

TestMyPriorityQueueMainClass.java

public class TestMyPriorityQueueMainClass {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
        Patient p1=new Patient("John",2);
        Patient p2=new Patient("Tom",9);
        Patient p3=new Patient("Jack",4);
        Patient p4=new Patient("Michael",6);

        MyPriorityQueue<Patient> priorityQueue=new MyPriorityQueue<>();
        priorityQueue.enqueue(p1);
        priorityQueue.enqueue(p2);
        priorityQueue.enqueue(p3);
        priorityQueue.enqueue(p4);

        while(priorityQueue.getSize()>0){
        	System.out.print(priorityQueue.dequeue()+"  ");
        }
	}
    static class Patient implements Comparable{
         private String name;
         private int priority;
         public Patient(String name,int priority){
        	 this.name=name;
        	 this.priority=priority;
         }
         public String toString(){
        	 return name+"(priority:"+priority+")";
         }
		@Override
		public int compareTo(Object oo) {//比较优先级
			// TODO Auto-generated method stub
			return this.priority-((Patient)oo).priority;
		}

    }
}

测试结果:优先级高的先输出,优先级最高的就是堆的根节点

时间: 2024-10-03 23:10:38

数据结构-堆实现优先队列(java)的相关文章

数据结构之基于堆的优先队列

优先队列的最重要的操作:删除最大元素(或最小)和插入元素.数据结构二叉堆能够很好的实现队列的基本操作.二叉堆的结点按照层级顺序放入数组,用长度为N+1的私有数组pq来表示一个大小为N的堆(堆元素放在pq[1]至pq[N]之间,为方便计数,未使用pq[0]),跟节点在位置1,它的子结点在位置2和3,以此类推.位置k的节点的父节点位置为k/2,它的两个子节点位置分别为2k和2k+1.当一颗二叉树的每个节点都大于等于它的两个子节点时,称为大根堆.当一颗二叉树的每个节点都小于等于它的两个子节点时,称为小

【C/C++学院】0828-STL入门与简介/STL容器概念/容器迭代器仿函数算法STL概念例子/栈队列双端队列优先队列/数据结构堆的概念/红黑树容器

STL入门与简介 #include<iostream> #include <vector>//容器 #include<array>//数组 #include <algorithm>//算法 using namespace std; //实现一个类模板,专门实现打印的功能 template<class T> //类模板实现了方法 class myvectorprint { public: void operator ()(const T &

堆数据结构+堆排序+最大优先队列的堆的实现

对于堆排序,首先要先知道什么是堆数据结构,堆数据结构就是一个完全二叉树,但是它有自己的性质. 例如最大堆的性质为:A[PARENT[i]]>=A[i]:即每一个结点的值大于等于其左右孩子的值,小于等于其父节点的值.我们在这里只讨论最大堆的情况.我们知道一颗完全二叉树对应一个最大堆的形式,我们要做的就是将二叉树转化为最大堆,这就是所谓的最大堆的维护,我们定义函数MaxheapFY(A,i)来进行操作. 代码: /** *MaxheapFY(A,i):维护位置i最大堆性质,此时假设left(i)和r

0038数据结构之堆和优先队列

优先队列:出队顺序和入队顺序无关,而是和优先级有关(优先级高的先出队) 如果使用普通线性结构或者顺序线性结构实现优先队列,出队或者入队总有一方是O(n)级别的:如果使用堆实现优先队列,能使入队和出队的时间复杂度都是O(logn),效率是极高的. 二叉堆是一颗完全二叉树,不一定是满二叉树,但是确实节点的那部分一定是在整棵树的右下侧.满足的规律:1)根节点最大, 2)确实节点的那部分在整棵树的右下侧.(低层次的节点不一定大于高层次的节点) 下图是一颗最大堆: 可以用数组存储: 从数组1位置开始存储:

堆与优先队列

当我们需要高效的完成以下操作时: 1.插入一个元素 2.取得最小(最大)的数值,并且删除 能够完成这种操作的数据结构叫做优先队列 而能够使用二叉树,完成这种操作的数据结构叫做堆(二叉堆) 堆与优先队列的时间复杂度: 若共有n个元素,则可在O(logn)的时间内完成上述两种操作 堆的结构如下图: 堆最重要的性质就是儿子的值一定不小于父亲的值,且堆从上到下,从左到右紧密排列. 堆的操作: 当我们希望向堆中插入元素时,堆的内部会进行如下操作(以插入元素3为例): (1.在堆的末尾插入该值) (2.不断

堆和优先队列

1 二叉堆和优先队列的概念 1.1 二叉堆 二叉堆堆是一个数组,它可以被看成一个近似的完全二叉树,树上每一个结点对应数组中的一个元素.除了最底层外,该树是完全充满的,而且是从左到右填充.表示堆的数组A包括两个属性:A.length给出数组元素的个数,A.heap_size表示有多少个堆元素存储在该数组中,这里,0<=A.heap_size<=A.length. 如下图所示: 堆可以分成两种:最大堆和最小堆.在最大堆中,任何节点的值都大于等于其孩子的值,故根节点是数组中的最大数所在节点.反之,最

数据结构--堆的实现(下)

1,堆作为优先级队列的应用 对于普通队列而言,具有的性质为FIFO,只要实现在队头删除元素,在队尾插入元素即可.因此,这种队列的优先级可视为按 时间到达 的顺序来衡量优先级的.到达得越早,优先级越高,就优先出队列被调度. 更一般地,很多应用不能单纯地按时间的先后来分优先级,比如按CPU占用时间或者其它方式……在这种情形下,使用堆更容易表达优先级队列. 2,堆的两个性质:①结构性质--堆从结构上看是一颗完全二叉树.然而,从物理存储上看,堆的实现基本上是使用一个一维数组存储堆中所有的结点.②orde

【转】用大顶堆实现优先队列

队列的特点是先进先出.通常都把队列比喻成排队买东西,大家都很守秩序,先排队的人就先买东西.但是优先队列有所不同,它不遵循先进先出的规则,而是根据队列中元素的优先权,优先权最大的先被取出.这就很像堆的特征:总是移除优先级最高的根节点. 重点:优先级队列,是要看优先级的,谁的优先级更高,谁就先得到权限.不分排队的顺序! 用堆实现优先队列: //最大堆 import java.util.ArrayList; public class Heap<E extends Comparable>{ priva

[ACM] POJ 1442 Black Box (堆,优先队列)

Black Box Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 7099   Accepted: 2888 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 empt