有时候很多基于文件的外部排序算法都需要合并两个有序的文件。下面就给出简单的C++实现方法。具体思路和合并两个有序的单链表的思路是一样的。
void merge_file(const string& file_in_name1,const string& file_in_name2,const string& file_out_name)
{
//打开两个输入文件和一个输出文件
ifstream fin1,fin2;
fin1.open(file_in_name1.c_str(),ios::in | ios::binary);
fin2.open(file_in_name2.c_str(),ios::in | ios::binary);
ofstream fout;
fout.open(file_out_name.c_str(),ios::out | ios::binary);
//在每个文件中先各读出第一个数
int temp1,temp2;
fin1.read(reinterpret_cast<char*>(&temp1),sizeof(int));
fin2.read(reinterpret_cast<char*>(&temp2),sizeof(int));
//在两个文件中前进,每次只选择两个文件中较小的那个数添加到输出文件的末尾
while (true)
{
if (temp1<=temp2)
{
fout.write(reinterpret_cast<const char*>(&temp1),sizeof(int));
//到文件的最后一个数读完之后,再读一次,保证每个文件中的所有数据都被读到。
fin1.read(reinterpret_cast<char*>(&temp1),sizeof(int));
if (fin1.eof())
{
break;
}
}
else
{
fout.write(reinterpret_cast<const char*>(&temp2),sizeof(int));
fin2.read(reinterpret_cast<char*>(&temp2),sizeof(int));
if (fin2.eof())
{
break;
}
}
}
if (!fin1.eof())
{
while (true)
{
//另一个文件已经读完了,说明当前这个文件中最后读到的那个整数还没有被写出,所以要先写出。
fout.write(reinterpret_cast<const char*>(&temp1),sizeof(int));
fin1.read(reinterpret_cast<char*>(&temp1),sizeof(int));
if (fin1.eof())
{
break;;
}
}
}
else
while (true)
{
fout.write(reinterpret_cast<const char*>(&temp2),sizeof(int));
fin2.read(reinterpret_cast<char*>(&temp2),sizeof(int));
if (fin2.eof())
{
break;
}
}
fin1.close();
fin2.close();
fout.close();
}
int main( void )
{
vector<int> a;
push_rand(a);
sort(a.begin(),a.end());
write_data_to_file(a,"data1.txt");
print_file("data1.txt");
a.clear();
push_order(a,100);
write_data_to_file(a,"data2.txt");
print_file("data2.txt");
merge_file("data1.txt","data2.txt","data.txt");
print_file("data.txt");
return 0;
}
main函数中用到了例如push_rand这样的函数,都是自己为了测试而写的,不是很重要。可以比较方便的实现,就不一一列出了。这个函数可以用于二路归并排序文件。K路归并的算法要做一些记录性的处理。在后面的博客中给出。