(算法总结)堆排序的应用:求数组中第k大的元素

(一)预备知识:堆与堆排序

二叉堆是一种非线性的数据结构,是一种完全二叉树的结构,分为大顶堆和小顶堆两种,其中大顶堆是指树中各父节点的值总是大于等于任何一个子节点的值;而小顶堆则是定义为树中各父节点的值总是小于等于任何一子节点的值。

一般用二叉堆实现优先级队列,其内部调整的时间复杂度为O(logN),C++的标准STL库的优先级队列包括以下5种操作:

(1)取堆顶操作:H.top()

(2)判断堆空操作:H.empty()

(3)添加元素入堆:H.push(int x)

(4)元素弹出堆:H.pop()

(5)求堆中元素个数:H.size()

其中,取堆顶和弹出堆操作都需要调整堆的结构,时间复杂度都是O(logN),而其他三个操作的时间复杂度都是O(1)。

(二)求数组中第k大的元素

已知一个未排序的数组,求该数组中的第K大元素,例如数组如下:

[3,2,1,5,6,4],k=2,第2大数字为5

算法设计:可以维护一个size为k的小顶堆Q,Q的堆顶用于存放每次的第k大的元素。将数组中的元素依次入堆,当Q.size()小于k时(堆并未建完),元素直接入堆;否则,判断当前元素x与堆顶元素Q.top()的大小,若x>Q.top(),说明此时的堆顶元素并非第k大,故将堆顶元素弹出,并将x入堆。

代码设计如下:

int findKthLargest(std::vector<int> nums, int k) {
	//	小顶堆
	std::prior queue<int, std::vector<int>, std::greater<int>> Q;
	for (int i=0; i<nums.size(); i++) {
		if (Q.size() < k) {
			Q.push(nums[i]);
		} else if (nums[i] > Q.top()) {
			Q.pop();
			Q.push(nums[i]);
		}
	}
	return Q.top();
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值