Top k问题【C语言 堆解决】

 Top k问题  

—1.找到n个数据中最大的k个数据(n>k)

—2.找n个数据中最小的k个数据(n>k)

思路分析

  • 建小堆解决最大的k个数据
  • 建大堆解决最小的k个数据

 以最大k问题为例:建一个数据数量为k个的小堆,若数据大于小堆的堆顶数据,则将2者数据进行交换,然后在进行向下调整,

小堆的性质:小的数据在堆顶,大的数据在后面

原因:我们将数组的前k个数据用来建一个k大小的小堆,建好堆后,我们将数组里下标为k的数据与此时堆顶的数据进行比较,若下标为k的数据大,则进堆;否则,不进堆。(这里时因为我们建的是小堆),

如果下标为k的数据进堆了,此刻观察根节点的左右子树,发现左右子树是小堆,那么就满足了向下调整算法的要求,用向下调整算法来处理。处理后,该堆是小堆,其根节点又是该队里最小的。

完成上述处理后,我们在不断的将新的堆顶(根节点)的数据与数组后的数据进行比较,交换,调整。(这里每处理一次后,若插入的数据大,则堆里最小的数据被弄出去)

  •  完成这些操作后,此时堆里的数据是数组里数据最大的前k个数据

代码实现 

void AdjustDown(HPDataType* a, int n, int root)
{
	int parent = root;//这是下标
	int child = 2 * parent + 1;//这是左子树的下标
	//这里先假设左子树是2个子树中最小的那个
     
	while (child < n)
	{
		//当右子树才是最小的时候,进行调整,让child + 1赋给child
		if (child + 1 < n && a[child] > a[child + 1])
		{
			//这里child+1<n,是为了防止出现数组越界,
			// 因为出现这中情况是,已经没意义了
			child = child + 1;
		}

		if (a[child] < a[parent])
		{
			swap(&a[child], &a[parent]);
			parent = child;
			child = 2 * parent + 1;
		}
		else
		{
			break;
		}

	}
}
HPDataType* getmaxnumbers(HPDataType* a, int arrsize, int k)
{
	HPDataType* arr = (HPDataType*)malloc(sizeof(HPDataType) * arrsize);
	for (int i = 0; i < k; i++);
	{
		arr[i] = a[i];
	}

	//建堆
	int n = arrsize;
	for (int j = (n - 1 - 1) / 2; j > 0; --j)
	{
		AdjustDown(arr, n, j);
	}
	for (int i = k; k < n; k++)
	{
		if (arr[0] < a[k])
		{
			arr[0] = arr[k];
			AdjustDown(arr, k, 0);
		}
	}
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值