有一堆二维坐标点<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;
}