优先队列和堆排序+排序方法总结

在这里插入图片描述


  • 优先队列的概念

  • 优先队列本身用堆实现。假设已经有一堆数据在优先队列中,把他们从队列里挨个取出来的过程我们就可以称之为堆排序。
  • 优先队列可以随时取队中最大值,插入等
  • 优先队列:出队顺序和入队顺序无关,和优先级有关。动态选择优先级高的执行
  • 普通队列:先进先出,后进后出

  • 堆的概念:

  • 即用完全二叉树来维护的一组数据。
  • 一般的,进行一次操作的时间复杂度在O(1)~O(logn)之间。
    在这里插入图片描述
    在这里插入图片描述
    那么我们如何保证二叉树有序呢?
    需要用到两种操作:

上浮:

如果父节点比k结点小,就交换他们的位置
在这里插入图片描述
代码实现:

private void swim(int k) {
   while (k > 1 && less(k/2, k)) {
      exch(k, k/2);
      k = k/2;
   }
}

下沉

如果k结点比它的两个子结点小,则与较大的那个交换
在这里插入图片描述
代码实现:

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;
   }
}

凭借以上两种方法我们可以构建出一个平衡的二叉树

插入操作:我们在二叉树末尾插入结点,再调用swim()方法使他上浮到正确的位置。

删除最大值操作:我们将要删除的元素和末尾元素交换位置,再删除想要删除的元素,并调用sink()方法使被交换元素下沉到正确位置,以此来保证二叉树有序
在这里插入图片描述
代码实现:

public void insert(Key v) {
		pq[++N] = v;
		if (N == 1 || min.compareTo(v) > 0) {
			min = v;
		}
		swim(N);
	}

	public Key delMax() {
		Key max = pq[1];
		exch(1, N--);
		pq[N + 1] = null;
		sink(1);
		if (isEmpty()) {
			min = null;
		}
		return max;
	}

两种方法图示:

在这里插入图片描述----------------------------------------------------------------------------------------
构造方法图示:

  • 我们在数组中间元素的位置依次调用sink方法来使二叉树有序
  • 用每次删除根节点的方法来使数组排序(经过sink方法后,父节点总是比子节点要大)
    在这里插入图片描述
    在这里插入图片描述
public class Heap {
	public static void sort(Comparable[] a) {
		int N = a.length;
		for (int k = N / 2; k >= 1; k--) {
			sink(a, k, N);
		}
		while (N > 1) {
			exch(a, 1, N--);
			sink(a, 1, N);
		}
	}

	private static void sink(Comparable[] pq, int k, int n) {
		while (2 * k <= n) {
			int j = 2 * k;
			if (j < n && less(pq, j, j + 1)) {
				j++;
			}
			if (!less(pq, k, j)) {
				break;
			}
			exch(pq, k, j);
			k = j;
		}
	}

	private static boolean less(Comparable[] pq, int i, int j) {
		return pq[i - 1].compareTo(pq[j - 1]) < 0;
	}

	private static void exch(Object[] pq, int i, int j) {
		Object swap = pq[i - 1];
		pq[i - 1] = pq[j - 1];
		pq[j - 1] = swap;
	}
  • 性能分析
  • 堆排序使我们所知的唯一一种可以同时利用时间和空间的方法,在最坏情况下它也能够保证用~2NlgN此比较和恒定的额外空间,当空间十分紧张时(比如嵌入式系统)它很流行
  • 是一种不稳定的排序,是原地排序
  • 时间复杂度:NlogN
  • 空间复杂度:1
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值