优先队列

优先队列是0个或多个元素的集合,每个元素都有一个优先权或值,对优先队列执行的操作有1) 查找;2) 插入一个新元素;3) 删除当访问元素时,具有最高优先级的元素最先删除(百度百科)。所以,每当插入数据时,我们都会利用堆来将数据进行排序,以方便读取并删除最大值。本代码中,用数组进行存储堆数据,插入数据时将数据存储在数组最后,然后在将其与父节点比较,若大于父节点,则与父节点交换,如此循环直至根节点为止。删除最大值时,将最后一个数据放入根节点位置,然后利用下沉即将父节点与最大子节点比较,若小于最大子节点则与之交换,若此循环,直至不小于任意子节点或者已经是叶子节点为止。

public class MaxPQ<Key extends Comparable<Key>> {
	private Key[] pq;//优先级队列
	private int N = 0;//当前元素的个数
	public MaxPQ(int MaxN)
	{
		pq = (Key[])new Comparable[MaxN + 1];//不能直接使用泛型创建对象,创建一个数组用于存放堆排序的数据,其中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 temp = pq[1];//存放最大值
		exch(1, N--);//将最后一个数据放入树根点,并减少数据的个数
		sink(1);//将根节点的数据利用堆排序进行下沉处理
		return temp;//返回最大值
	}
	public boolean less(int i, int j)//判断数组a中a[i]是否小于a[j]
	{
		return pq[i].compareTo(pq[j]) < 0; 
	}
	public void exch(int i, int j)//交换i和j的数据
	{
		Key temp = pq[i];
		pq[i] = pq[j];
		pq[j] = temp;
	}
	//堆排序上浮
	public void swim(int k)
	{
		while(k > 1 && less(k/2, k))
		{
		//因为二叉堆中节点的父节点为k/2,子节点为2k,2k+1
			exch(k/2, k);//交换两者位置
			k = k/2;
		}
	}
	//堆排序下沉
	public void sink(int k)
	{
		while(2 * k + 1 <= N)
		{
			int j = 2 * k;//左子节点
			if(less(j, j + 1))
				j++;//取较大的子节点索引赋给j
			//若父节点不小于任意子节点,则结束
			if(!less(k, j))
				break;
			exch(k, j);//交换父节点和最大子节点
			k = j;//继续判断交换后的子节点是否下沉
		}
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		MaxPQ<String> a = new MaxPQ<String>(10);
		a.insert("A");
		a.insert("S");
		a.insert("X");
		a.insert("W");
		a.insert("B");
		a.insert("Z");
		a.insert("a");
		String t = a.delMax();
		System.out.println(t);
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值