实验目的:
- 掌握最小堆的基本概念,堆的基本运算以及堆排序的流程
- 掌握有理数类的定义及逻辑运算规则
实验内容:
- 完成有理数的类定义以及有理数逻辑运算函数
class Rational{
friend bool operator<(const Rational& r1, const Rational& r2) {}
friend bool operator<=(const Rational& r1, const Rational& r2) {}
friend bool operator>(const Rational& r1, const Rational& r2) {}
friend bool operator>=(const Rational& r1, const Rational& r2) {}
friend bool operator==(const Rational& r1, const Rational& r2) {}
friend bool operator!=(const Rational& r1, const Rational& r2) {}
public:
int N;
int D;
Rational() {}
Rational(int n){}
Rational(int n, int d) {}
Rational(const Rational& r){}
Rational& operator=(const Rational& r) {}
};
- 创建有理数的最小堆,实现siftdown, siftup, insert等功能
- 实现基于最小堆的堆排序,按从小到大的顺序输出有理数
- 为在线测评系统检测程序的运行,对程序文档及IO做如下规范:
(1).所有类、函数及主程序都写在一个单cpp文档里,不能有其他include用的.h或.cpp文档
(2).程序不能输出任何提示用的字符串
(3).输入: 第一行包含一个整数T (1T105);接下来的T行,每一行有两个整数n, d (|n|<103, 0<d<103),用空格隔开,表示输入的有理数的分子和分母。
(4).输出:第一行输出有理数的最小堆序列,第二行输出从小到大排序后的序列。
(5).输出的每个有理数必须规约,以n/d的形式输出,其中d>0且gcd(n,d)=0;如果d=1或n=0则直接输出n
输入样例:
5
3 2
1 3
4 2
12 10
4 6
输出样例:
1/3 2/3 2 6/5 3/2
1/3 2/3 6/5 3/2 2
代码实现:
#include <iostream>
using namespace std;
int gcd(int a, int b) {
if (a % b == 0) return b;
return gcd(b, a % b);
}
class Rational {
friend bool operator<(const Rational& r1, const Rational& r2) { return r1.N * r2.D < r1.D* r2.N; }
friend bool operator<=(const Rational& r1, const Rational& r2) { return r1.N * r2.D <= r1.D * r2.N; }
friend bool operator>(const Rational& r1, const Rational& r2) { return r1.N * r2.D > r1.D * r2.N; }
friend bool operator>=(const Rational& r1, const Rational& r2) { return r1.N * r2.D >= r1.D * r2.N; }
friend bool operator==(const Rational& r1, const Rational& r2) { return r1.N * r2.D == r1.D * r2.N; }
friend bool operator!=(const Rational& r1, const Rational& r2) { return r1.N * r2.D != r1.D * r2.N; }
public:
int N;
int D;
Rational() {}
Rational(int n) { N = n; D = 1; }
Rational(int n, int d) {
if (n == 0) { N = n; D = d; }
else {
int c;
if (n > 0) c = gcd(n, d);
else if (n < 0) c = gcd(-n, d);
N = n / c; D = d / c;
}
}
Rational(const Rational& r) { N = r.N; D = r.D; }
Rational& operator=(const Rational& r) { N = r.N; D = r.D; return *this; }
void printhelp() {
if (N == 0) cout << 0;
else if (D == 1) cout << N;
else cout << N << '/' << D;
return;
}
};
void swap(Rational* A, int i, int j) {
Rational tem = A[i];
A[i] = A[j];
A[j] = tem;
return;
}
class heap {
private:
Rational* Heap;
int maxsize;
int n;
void siftdown(int pos) {
while (!isLeaf(pos)) {
int j = leftchild(pos);
int rc = rightchild(pos);
if ((rc < n) && (Heap[rc] < Heap[j]))
j = rc;
if (Heap[pos] < Heap[j]) return;
swap(Heap, pos, j);
pos = j;
}
return;
}
void siftup(int curr) {
while ((curr != 0) && (Heap[curr] < Heap[parent(curr)])) {
swap(Heap, curr, parent(curr));
curr = parent(curr);
}
return;
}
public:
heap(Rational* h, int num, int max)
{
Heap = h; n = num; maxsize = max; buildHeap();
}
int size() const { return n; }
bool isLeaf(int pos) const
{
return (pos >= n / 2) && (pos < n);
}
int leftchild(int pos) const
{
return 2 * pos + 1;
}
int rightchild(int pos) const
{
return 2 * pos + 2;
}
int parent(int pos) const
{
return (pos - 1) / 2;
}
void buildHeap()
{
for (int i = n / 2 - 1; i >= 0; i--) siftdown(i);
}
void printheap() {
for (int i = 0; i < n; i++) {
Heap[i].printhelp();
cout << " ";
}
return;
}
void insert(const Rational& it) {
if (n >= maxsize) { cout << "Heap is full" << endl; return; }
int curr = n++;
Heap[curr] = it;
siftup(curr);
return;
}
Rational removefirst() {
if (n <= 0) { cout << "Heap is empty" << endl; return NULL; }
swap(Heap, 0, --n);
if (n != 0) siftdown(0);
return Heap[n];
}
Rational remove(int pos) {
if ((pos < 0) && (pos >= n)) { cout << "Bad position" << endl; return NULL; }
if (pos == (n - 1)) n--;
else {
swap(Heap, pos, --n);
siftup(pos);
if (n != 0) siftdown(pos);
}
return Heap[n];
}
};
void heapsort(heap H, int n) {
Rational maxval;
for (int i = 0; i < n; i++)
maxval = H.removefirst();
return;
}
int main() {
int n = 0;
cin >> n;
Rational A[10];
for (int i = 0; i < n; i++) {
int n1, d1;
cin >> n1 >> d1;
A[i] = Rational(n1, d1);
}
heap a(A, n, n);
a.printheap();
cout << endl;
heapsort(a, n);
for (int i = n-1; i >= 0; i--) {
A[i].printhelp();
if(i==0)
cout << endl;
else cout << " ";
}
return 0;
}