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

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

这里用大小为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

猜你喜欢

转载自blog.csdn.net/qq_41973536/article/details/80171694