基于二叉堆的优先队列java实现

本文介绍了一种基于数组实现的最大堆数据结构,并提供了插入、删除最大元素等关键操作的实现细节。通过具体示例展示了如何维护堆的有序性,包括上浮与下沉算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

堆有序的·二叉树,就是每个节点值都是大于等于它的子节点值。

这里用大小为N+1的数组pq来表示一个大小为N的堆,不使用pq[0]。

关于二叉树,有一个特点很重要,就是位置k的父节点是k/2,子节点是2*k和2*k+1。

 

堆的有序化,包括两种情况:

1.当某个节点的值增大时,采用的是由下至上的堆有序化,比较该节点与它的父节点的值,并根据比较结果交换位置。定义方法swim(上浮)。

2.当某个节点的值减小时,采用的是由上至下的堆有序化,比较该节点与它的较大的那个子节点的值,并根据比较结果交换位置。定义方法sink(下沉)。

实现如下:

package MaxPQ;

public class MaxPQ<Key extends Comparable<Key>>{
	private Key[] pq;
	private int N= 0;
	public MaxPQ(int maxN){
		pq =(Key[]) new Comparable[maxN+1];
	}
	public boolean isEmpty() {
		return N==0;
	}
	public int size() {
		return N;
	}
	public void insert(Key key) {
		pq[++N] =key;
		swim(N);
	}
	
	public Key delMax() {
		Key re =pq[1];
		exch(1,N);
		pq[N] =null;
		N--;
		sink(1);
		return re;
	}
	
	private void sink(int k) {//由上至下的堆有序化
		while (2*k<=N) {
			int j =2*k;
			if (less(j,j+1)) {
				j=j+1;
			}
			if (!less(k,j)) {
				break;
			}
			else {
				exch(k,j);
				k = j;
			}
		}
	}
	private void swim(int k) {//由下至上的堆有序化
		while (k>1&&less(k/2,k)) {
			exch(k/2,k);
			k =k/2;
		}	
	}
	private void exch(int i, int j) {//交换第i、j个值
		Key key = pq[i];
		pq[i] = pq[j];
		pq[j] = key;	
	}
	private boolean less(int i, int j) {//判断第i个值是否比第j个值小
		return pq[i].compareTo(pq[j])<0;
	}

}

测试如下:

package MaxPQ;

public class Test {
	public static void main(String[] args) {
		MaxPQ<Integer> m =new MaxPQ<Integer>(11);
		System.out.println(m.isEmpty());
		m.insert(2);
		m.insert(6);
		m.insert(4);
		m.insert(7);
		m.insert(0);
		m.insert(8);
		m.insert(3);
		m.insert(5);
		System.out.println(m.size());
		System.out.println(m.delMax());
		System.out.println(m.delMax());
		System.out.println(m.size());
		System.out.println(m.isEmpty());
	}

}

 

结果如下:

 

 

true
8
8
7
6
false

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值