多路归并的外排序

本文介绍了一种基于多路归并的外排序算法实现,通过构造输入流最小堆进行文件排序。具体步骤包括:建立输入流最小堆、读取元素、调整堆结构等,并附带示例代码及测试样例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >



//多路归并的外排序 


//思路如下:
//1.按各输入文件中下一个读到的元素的大小构造一个输入流最小堆.
//2.从堆顶文件里读一个元素并写入输出文件. 
//3.同时按读的那个文件的下一个元素的值调整堆.
//4.若第3步已到达文件结尾.则从堆中删除该输入流
//5 如果堆中还有元素. 回到第2步


#include<iostream>
#include<fstream>
#include<vector>
#include<algorithm>
#include<iterator>
#include<functional>
using namespace std;


//这个类主要用来管理一个输入流.
//它知道流中还有没有元素.
//可以查看下一个将读出来的元素的值.
//可以读出一个元素.
template <class T>
class Yudu {
private:
istream & _istream;
T _next;
bool _have_next;
public:
Yudu( istream & x) : _istream(x) {
if (_istream >> _next) _have_next = true;
else _have_next = false;
}
inline bool have_next() { return _have_next; }
//读出流中下一个元素
T read_next() {  
if (! _have_next) {
cout << "读取错误! 退出" << endl;
exit(1);
}
T temp = _next;
if (_istream >> _next)
_have_next = true;
else
_have_next = false;
return temp;
}
//看看下一个元素但不读出来
inline const T& look_next() const { return _next; }
};


//比较两个Yudu对象下一个元素的大小
//提供给paixu函数中的堆操作时使用
class bijiao
{
public:
template <typename T>
bool operator() (const Yudu<T>* a, const Yudu<T>* b) {
return a->look_next() > b->look_next() ;
}
};


//文件排序函数
template <typename T>
void paixu(vector<Yudu<T>* >& v , ostream& out){
//先删除数组中的"没有下一个元素"的Yudu对象.例如一个空的文件构造的Yudu对象.
v.erase( remove_if(v.begin(),v.end(),
not1(mem_fun(& Yudu<T>::have_next))), v.end() );

make_heap(v.begin(), v.end(), bijiao());

while (! v.empty() ){
pop_heap(v.begin(),v.end(), bijiao());
out << v.back()->read_next() << " ";   // out 以文本方式打开. 如果是其它方式这里要改.
if (! v.back()->have_next() )
v.pop_back();
else
push_heap(v.begin(), v.end(), bijiao());
}
}

int main() {
ifstream in[3];
in[0].open("1.txt");
in[1].open("2.txt");
in[2].open("3.txt");

vector<Yudu<int>* > v;
v.push_back(new Yudu<int>(in[0])); //实际使用时要释放new出的对象.或者用boost的智能指针.
v.push_back(new Yudu<int>(in[1]));
v.push_back(new Yudu<int>(in[2]));

ofstream o("out.txt");

paixu(v, o);

cin.get();
return 0;
}

/*
测试(三个文件中是已经有序的数)
1.txt:  1 5 9 12 21
2.txt:  3 4 5 7 8
3.txt:  2 3 5 10 11 14 19 25 27

执行归并后
out.txt:
1 2 3 3 4 5 5 5 7 8 9 10 11 12 14 19 21 25 27
  */

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值