优先队列(algs4)


                                             泛型优先队列的API

     

public class MaxPQ<Key extends Comparable<Key>>                            

private Key[] pq                                  基于堆的完全二叉树     

private int N                                        最大的n个数  

public MaxPQ(int maxN)                        创建一个初始容量为maxN+1的优先队列                     

public boolean isEmpty()                        返回队列是否为空      

public int size()                                     返回优先队列元素个数   

public void insert(Key v)                         向优先队列中插入一个元素      

public Key delMax()                               删除并返回最大元素            

private boolean less(int i,int j)                  比较      

private void exch(int i,int j)                      交换 

private void swim(int k)                         由下至上的堆有序化(上浮)

private void sink(int k)                          由上至下的堆有序化(下沉)



                                                     

package _2_Sorting;
/** 算法2.6 基于堆的优先队列
 * 优先队列支持两种操作:删除最大元素和插入元素;基于堆的实现能保证在对数时间内完成它们。
 * 优先队列由一个基于堆的完全二叉树表示,存储于数组pq[1...N]中
*/
public class MaxPQ<Key extends Comparable<Key>>
{
	private Key[] pq;     /*基于堆的完全二叉树*/
	private int N=0;     /*存储于pq[1..N]中,pq[0]没有使用*/
	public MaxPQ(int maxN)
	{
		pq =(Key[]) new Comparable[maxN+1];  /*[maxN+1]:因为pq[0]未使用*/
	}
	public boolean isEmpty()
	{
		return N==0;
	}
	public int size()
	{
		return N;
	}
	public void insert(Key v)
	{/*插入元素
	将新元素添加到数组末尾,增加堆的大小,并让新元素上浮到合适的位置*/
		pq[++N]=v;
		swim(N);
	}
	public Key delMax()
	{/*删除最大元素
	从数组顶端删去最大元素,将数组最后一个元素放到顶端,减小堆的大小并让这个元素下沉到合适的位置*/
		Key max=pq[1];         /*从根节点得到最大元素*/
		exch(1,N--);          /*将其和最后一个节点交换*/
		pq[N+1]=null;         /*防止对象游离*/
		sink(1);              /*恢复堆的有序性*/
		return max;
	}
	private boolean less(int i,int j)
	{
		return pq[i].compareTo(pq[j])<0;
	}
	private void exch(int i,int j)
	{
		Key t=pq[i];
		pq[i]=pq[j];
		pq[j]=t;
	}
	private void swim(int k)
	{/*由下至上的堆有序化(上浮)
	当一个节点太大时它需要浮到堆的更高层*/
		while(k>1&&less(k/2,k))
		{
			exch(k/2,k);
			k=k/2;
		}
	}
	private void sink(int k)
	{/*由上至下的堆有序化(下沉)
	当一个节点太小时它需要沉到堆的更低层*/
		while(2*k<=N)
		{
			int j=2*k;
			if(j<N&&less(j,j+1))
				j++;         /*找出较大的子节点*/
			if(!less(k,j))   /*是否上浮*/
					break;
			exch(k,j);
			k=j;
		}
	}
}

                                  

                                     

package _2_Sorting;

import java.util.Scanner;
import _1_3linkedList.Stack;;
/**一个优先队列的用例
*/
public class TopMin
{

	public static void main(String[] args)
	{                                 /*打印输入流中最大的M行*/
		Scanner sc=new Scanner(System.in);
		int M=sc.nextInt();
		System.out.print("请输入"+M+"个Integer类型元素:");
		MaxPQ<Integer> pq=new MaxPQ<Integer>(M+1); /*行23:如果优先队列中存在M+1个元素....*/
		while(true)
		{
			Integer n=sc.nextInt();
			
			if(n==-100)               /*-100表示输入结束*/
				break;
			pq.insert(n);                /*放入优先队列*/
			if(pq.size()>M)            /*如果优先队列中存在M+1个元素则删除其中最小的元素*/
				pq.delMax();  
		}                            /*最大的M个元素都在优先队列里*/
		Stack<Integer> stack=new Stack<Integer>();
		while(!pq.isEmpty())
		{
			stack.push(pq.delMax());
		}
		for(Integer i:stack)
			System.out.print(i+" ");
	}

}
















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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值