外部排序,C++实现
2016-05-02 23:26
337 查看
外部排序,C++实现
K个排序的数组合并,用到了败者树相关内容参考了,严蔚敏的《数据结构》
// // Created by Han on 16/5/2. // #include <iostream> #include <cstdio> #include <vector> #include <string> #include <sstream> #include <cstring> #include <fstream> #include <algorithm> using namespace std; const int MYMAX = 123456789; const int MYMIN = -123456789; int invalid_count = 0; void Adjust_LoserTree(int s,vector<int>& loser_tree,const vector<int>& input_vals) { int K = loser_tree.size(); int parent = (s+K)/2;//notice while(parent > 0){ if(input_vals[s] > input_vals[loser_tree[parent]]){ // s为当前胜者 int tmp = s; s = loser_tree[parent]; loser_tree[parent] = tmp; } parent = parent/2; } loser_tree[0] = s; } void Build_LoserTree(vector<int>& loser_tree, vector<int>& input_vals) { int K = input_vals.size() -1; loser_tree.resize(K); //init input_vals[K] = MYMIN; for(size_t i=1;i<K;++i){ loser_tree[i] = K; } for(int i=K-1;i>=0;--i){ Adjust_LoserTree(i,loser_tree,input_vals); } } int get_value(ifstream& i_fstream, bool& if_valid) { int res_val = MYMAX; int val; if(if_valid){ if(i_fstream >> val){ //未达到eof res_val = val; } else{ if_valid = false; invalid_count += 1; } } return res_val; } void Merge_KSort(vector<ifstream*> &i_fstreams,ofstream* o_fstream) { size_t K = i_fstreams.size(); bool* valid_streams = new bool[K](); for(size_t i=0;i<K;++i){ valid_streams[i] = true; } vector<int> input_vals; input_vals.resize(K+1);//facilitate to build loser tree for(size_t i=0;i<K;++i){ input_vals[i] = get_value(*(i_fstreams[i]),valid_streams[i]); } //Build loser tree vector<int> loser_tree; Build_LoserTree(loser_tree,input_vals); //find min and adjust while(invalid_count < K){ int sel_id = loser_tree[0]; *o_fstream << input_vals[sel_id] << " " << flush; input_vals[sel_id] = get_value(*(i_fstreams[sel_id]),valid_streams[sel_id]); Adjust_LoserTree(sel_id,loser_tree,input_vals); } //close stream for(size_t i=0;i<i_fstreams.size();++i){ (*(i_fstreams[i])).close(); } (*o_fstream).close(); } void InterSort(string file_name) { ifstream i_fstream(file_name); vector<int> vals; int val; while(i_fstream >> val){ vals.push_back(val); } sort(vals.begin(),vals.end()); i_fstream.close(); ofstream o_fstream(file_name); for(size_t i=0;i < vals.size();++i){ o_fstream << vals[i] << " " << flush; } o_fstream.close(); } int main() { //input files vector<string> file_names; string my_dir = "/Users/HAN/Documents/"; file_names.push_back(my_dir + "data1.txt"); file_names.push_back(my_dir + "data2.txt"); file_names.push_back(my_dir + "data3.txt"); size_t K = file_names.size(); //InterSort for every file for(size_t i=0;i<K;++i){ InterSort(file_names[i]); } //input streams vector<ifstream*> input_streams; for(size_t i=0;i<K;++i){ ifstream* input_stream = new ifstream(file_names[i]); input_streams.push_back(input_stream); } //output file string output_file = my_dir + "data.txt"; ofstream output_stream(output_file); //merger sort for k input streams to output stream Merge_KSort(input_streams,&output_stream); }
测试用例:
输入
data1.txt: 3 8 9 7 6
data2.txt: 0 2 6 7 8 1
data3.txt: 0 1 2 5 9 8 7 6
输出
data.txt: 0 0 1 1 2 2 3 5 6 6 6 7 7 7 8 8 8 9 9
相关文章推荐
- 使用VS开发C语言
- [LeetCode#3][C]Longest Substring Without Repeating Characters
- C++中创建临时对象的情况
- 【AKOJ】1298-B趣味求和
- C++实现的十字链表:容器和迭代器
- 第6周 C语言及程序设计提高例程-24 数组名作为函数参数
- 转载:C++编译期多态与运行期多态
- 交叉编译多个cpp或者c文件自动构建Makefile
- 标准C++中string的使用++
- c++primer第二遍阅读感悟(chap2)
- C语言学习笔记
- 第6周 C语言及程序设计提高例程-22 用指针法访问数组元素
- 一起talk C栗子吧(第一百四十五回:C语言实例--socket概述)
- C++ 结构体指针的定义
- C++高级编程(一)——运算符重载
- c++学习(x.x)总括
- C语言下的运算符
- 学习笔记之深入浅出MFC 第8章 C++重要性质---构造函数与析构函数
- C++基础实例-结构类型(3)
- C++大数问题