堆排序应用之优先队列的实现

我在上一篇博客中写了堆排序。在这篇文章中我对上篇的进行了一点改变,比如说方法和实例变量的访问级别。

优先队列的定义:一种用来维护由一组元素构成的集合S的数据结构,其中的每一个元素都有一个相关的值称为关键字。

优先队列可以实现的操作有下方四个:

MAX_HEAP_INSERT(int key):将值为key的元素插入集合中。

HEAP_MAXIMUN():返回堆中值最大的元素。

HEAP_EXTRACT_MAX():去掉并返回S中的具有最大关键字的元素。

HEAP_INCREASE_KEY(int i, int key):将位于i处的值变为key,且key的值大于原来的值。

具体实现代码和测试代码如下:

package algorithms;

import java.util.ArrayList;

public class PriorityQueue {
	private int heap_size;
	private ArrayList<Integer> A;

	private PriorityQueue() {
		this.A = new ArrayList<Integer>();
		this.heap_size = 0;
	}
	private PriorityQueue(ArrayList<Integer> A) {
		this.A = A;
		this.heap_size = A.size();
	}

	private int LEFT(int i) {
		return (i << 1) + 1; // 括号必须要,否则先做加法运算
	}

	private int RIGHT(int i) {
		return (i << 1) + 2;
	}

	private int PARENT(int i) {
		return (i - 1) >> 1;
	}

	private void SWAP(ArrayList<Integer> A, int i, int j) {
		int temp = A.get(i);
		A.set(i, A.get(j));
		A.set(j, temp);
		return;
	}

	public int HEAP_MAXIMUM() {
		return A.get(0);
	}

	private void MAX_HEAPIFY(ArrayList<Integer> A, int i) {
		int Largest = i;
		int L = LEFT(i), R = RIGHT(i);
		if (L < this.heap_size && A.get(L) > A.get(i)) {
			Largest = L;
		}
		if (R < this.heap_size && A.get(R) > A.get(Largest)) {
			Largest = R;
		}

		if (Largest != i) {
			SWAP(A, i, Largest);
			MAX_HEAPIFY(A, Largest);
		}
	}

	public int HEAP_EXTRACT_MAX() {
		int max = A.get(0);
		A.set(0, A.get(this.heap_size - 1));
		this.heap_size--;
		MAX_HEAPIFY(A, 0);
		A.remove(heap_size);
		return max;
	}

	public boolean HEAP_INCREASE_KEY(int i, int key) {
		if (key < A.get(i)) {
			System.out.println("the new key is smaller then current key");
			return false;
		}
		A.set(i, key);
		for (int j = PARENT(i); j >= 0; j = PARENT(j)) {
			if (key > A.get(j)) {
				A.set(i, A.get(j));
				i = j;
			} else {
				A.set(i, key);
			}
		}
		if (i == 0) {
			A.set(i, key);
		}
		return true;
	}

	public boolean MAX_HEAP_INSERT(int key) {
		this.A.add(Integer.MIN_VALUE);
		this.heap_size++;
		return HEAP_INCREASE_KEY(this.heap_size-1, key);
	}

	public static void main(String[] args) {
		int[] in = new int[]{16,14,10,8,7,9,3,2,0,1};

		ArrayList<Integer> A = new ArrayList<Integer>();
		for (Integer integer : in) {
			A.add(integer);
		}
		for (Integer integer : A) {
			System.out.print(integer+",");
		}System.out.println("                 "+A.size());
		PriorityQueue priorityQueue = new PriorityQueue(A);
		System.out.println(priorityQueue.HEAP_MAXIMUM());
		System.out.println(priorityQueue.HEAP_INCREASE_KEY(8, 180));
		for (Integer integer : A) {
			System.out.print(integer+",");
		}System.out.println("                 "+A.size());
		
		System.out.println(priorityQueue.HEAP_EXTRACT_MAX());
		for (Integer integer : A) {
			System.out.print(integer+",");
		}System.out.println("                 "+A.size());
		System.out.println(priorityQueue.MAX_HEAP_INSERT(180));
		for (Integer integer : A) {
			System.out.print(integer+",");
		}System.out.println("                 "+A.size());
	}

}

测试结果如下:



MAX_HEAP_INSERT(int key)的时间复杂度为O(lgn)。

HEAP_MAXIMUN()的时间复杂度为O(1)。

HEAP_EXTRACT_MAX()的时间复杂度为O(lgn),因为除了时间复杂度为O(lgn)的MAX_HEAPIFY以外(看我上篇博客如何求MAX_HEAPIFY的时间复杂度),它的其他操作都是常数阶的。

HEAP_INCREASE_KEY(int i, int key)的时间复杂度为O(lgn)。

最后,总之在一个包含n个元素的堆中,所有的优先队列的操作都可以在O(lgn)的时间内完成。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值