利用大顶堆实现top-k算法

有一堆二维坐标点<x1,y1>, <x2, y2>……<xn, yn>, 现在有两个问题:
给出n个坐标点,请对他们进行堆排序。坐标点的大小关系是:如果 xi> xj, 则 <xi,yi> 大于 <xj, yj>. 若 xi=xj 且 yi >yj, 那么同样有<xi,yi> 大于 <xj, yj>.
假定坐标点是一个一个来的,请利用堆,能时刻报告数据中的最小的k项。比如k=1, 有4个坐标数据 <2,2>, <1,1>, ❤️,3>, <0,0> 依次到来。那么当来第一个<2,2>时, top-1的值是<2,2>, 再来一个数据<1,1>,这时top-1的值变为了 <1,1>, 再来一个<3,3>数据,top-1还是<1,1>, 第四个数据<0,0>到了后,top-1 就变为了 <0,0>。

解题过程:坐标我是通过一个Heap_node的类实现的,这个类的私有成员是一个int型左值和右值。
第一问通过一个建堆、调整堆、排序输出的函数实现将堆中的元素从小到大输出。
题目的第一个描述,老师建议使用操作符重载,但是我不太会用。。。所以还是用一个函数实现了。
第二问,根据题目的描述,可以用一个大顶堆实现。老师推荐的方法是开辟一个大小为k的数组存储数据,将这个数组构建成大顶堆,每次输入一个数据,比较它和数组第一个数据即堆顶的大小,如果比堆顶小,就让它取代堆顶,并重新调整这个大顶堆。这个调整的函数也比较容易实现。那么这个数组的所有的元素就是这个堆的top-k,同时也实现了实时性,还是比较有特点的一道题!
代码不足之处:1.输入数据存储成一个个的坐标的过程不够简洁,但是又没有想到更好的办法,同学有用二维数组做的,但是也不够简洁。
2.因为堆的数据结构经常使用,老师推荐把它写成模板类,后序还需要补充。

//Heap_node.h
class Heap_node
{
public:
	Heap_node();
	int get_left();
	int get_right();
	void to_left(int a);
	void to_right(int b);
private:
	int left;
	int right;
};
//Heap_node.cpp
Heap_node::Heap_node()
{
}
int Heap_node::get_left()
{
	return left;
}
int Heap_node::get_right()
{
	return right;
}
void Heap_node::to_left(int a)
{
	left = a;
}
void Heap_node::to_right(int b)
{
	right = b;
}
//Heap.h
using namespace std;
class Heap
{
public:
	void Add(Heap_node m,Heap_node A[],int length);
	void MaxHeapify(Heap_node A[], int length, int i);
	void BuildHeap(Heap_node A[], int length);
	void Sort(Heap_node A[], int length);
private:
	bool Greater(Heap_node a, Heap_node b);
};

//Heap.cpp
void Heap::MaxHeapify(Heap_node A[], int length, int i)
{
	int n_left = i * 2+1;  //节点i的左孩子
	int n_right = i * 2 + 2; //节点i的右孩子节点
	int max = i;  //父节点
	if (n_left <length && Greater(A[n_left],A[max]))
		max = n_left;
	if (n_right < length && Greater(A[n_right],A[max]))  
		max = n_right;
	if (i != max)   //最小值不是父节点
	{
		Heap_node temp = A[max]; //exchange
		A[max] = A[i];
		A[i] = temp;
		MaxHeapify(A,length,max);
	}
}

bool Heap::Greater(Heap_node a, Heap_node b)
{
	if (a.get_left() > b.get_left() || a.get_right() > b.get_right())
		return true;
	else
		return false;
}
void Heap::Add(Heap_node m,Heap_node A[],int length)
{
	if (Greater(A[0],m))
	{
		A[0] = m;
		MaxHeapify(A,length,0);
	}
}
void Heap::BuildHeap(Heap_node A[], int length)
{
	int parent = (length-2) / 2;
	for (int i = parent; i >= 0; i--)
		MaxHeapify(A, length, i);
}
void Heap::Sort(Heap_node A[], int length)
{
	int count = length;
	while (count != 0)
	{
		Heap_node temp = A[0];
		A[0] = A[count - 1];
		A[count - 1] = temp;
		count--;
		MaxHeapify(A, count, 0);
	}
	for (int i = 0; i < length; i++)
		cout << A[i].get_left() << "," << A[i].get_right() << " ";
}
//main.cpp
using namespace std;
const int k=2;
int main()
{
	Heap_node M[10];
	Heap t;
	int n, count1 = 0, n_count1 = 0;
	while (cin >> n)
	{
		if (n_count1 % 2 == 0)
			M[count1].to_left(n);
		else
		{
			M[count1].to_right(n);
			count1++;
		}
		n_count1++;
		if (cin.get() == '\n')
			break;
	}
	t.BuildHeap(M, count1);
	t.Sort(M,count1);
	Heap_node H[10],A[k];
	for (int i = 0; i < k; i++)
	{
		A[i].to_left(1000);
		A[i].to_right(1000);
	}
	Heap h;
	int m,count=0,n_count=0;
	while (cin >> m)
	{
		if (n_count % 2 == 0)
			H[count].to_left(m);
		else
		{
			H[count].to_right(m);
			h.Add(H[count], A, k);
			for (int i = 0; i < k; i++)
				cout << A[i].get_left() << "," << A[i].get_right() << "  ";
			count++;
		}
		n_count++;
		if (cin.get() == '\n')
			break;
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值