排序算法整理(6)堆排序的应用,top K 问题

本文介绍了如何利用堆排序解决top K问题,避免了完全排序的冗余操作。主要步骤包括建立最小堆,与剩余元素比较并调整堆,最终达到在O(n lgK)的时间复杂度内找出前K个最大数。核心代码和完整实现提供了详细的过程演示。
摘要由CSDN通过智能技术生成

top K问题是这样的,给定一组任意顺序的数,假设有n个。如何尽快地找到它们的前K个最大的数?

首先,既然是找前K个最大的数,那么最直观的办法是,n个数全部都排序,然后挑出前K个最大数。但是这样显然做了一些不必要的事儿。

利用堆这种数据结构,借助前文《排序算法整理(5)堆排序》中谈到的维护堆的函数, min_heapify( ),就可以轻松解决top K问题。

主要步骤如下:

step 1. 随意选出K个数,挑出这K个数的最小的数。这个过程可以用最小堆完成。

step 2. 在剩下的n – K个数中,挑出任意一个数m,和最小堆的堆顶进行比较,如果比最小堆的堆顶大,那么说明此数可以入围前K的队伍,于是将最小堆的堆顶置为当前的数m。

step 3. 调整最小堆。时间复杂度为Olg(K),由于K是constant(常数级别),所以时间复杂度可以认为是常数级别。

step 4. 重复进行step 2 ~ step 3,直到剩下的n – K个数完成。进行了n –constant次,时间复杂度为O(n lgK).

 

核心代码如下:

void top_k(int * p_arr, int length,int k, int * p_res)
{		
	int * adjusted_array =  new int[k+1];
	adjusted_array[0]=0;
	for(int i=0;i<k;i++) //构建前k名构成的堆。
		adjusted_array[i+1]=p_arr[i];
	build_heap_min(adjusted_array,k);
	for(int j=k;j<length;j++)
	{
		if(adjusted_array[1]<p_arr[j])
		{
			adjusted_array[1]=p_arr[j];
			min_heapify_recur(adjusted_array,1,k);
		}
	}	
	for(int m=1;m<=k;m++)	
		p_res[m-1]=adjusted_array[m];		
	delete [] adjusted_array;//拷贝给p_res后再删除adjusted_array	
	return;	
}

完整实现代码如下。有heap.h和heap.cpp和main.cpp这3个文件。

这是heap.h

//heap.h文件
#include <stdio.h>
#include <stdlib.h>
inline int
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值