归并排序(用容器实现)
基础排序算法之: 归并排序
- 思想:
归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。(来自百度百科)
有点抽象把,不急,我们上图。
清楚多了把。
- 特点:
稳定的排序算法
时间复杂度O(nlogn) 、空间复杂度O(n)
- 实现
1 vector<int> mergeArray(vector<int>& left, vector<int>& right) 2 {//合并 3 auto l = left.begin(); 4 auto r = right.begin(); 5 vector<int> vec; 6 while (l != left.end() && r != right.end()) 7 { 8 if (*l < *r) 9 { 10 vec.push_back(*l); 11 l++; 12 } 13 else 14 { 15 vec.push_back(*r); 16 r++; 17 } 18 } 19 while (l != left.end()) 20 { 21 vec.push_back(*l); 22 l++; 23 } 24 while (r != right.end()) 25 { 26 vec.push_back(*r); 27 r++; 28 } 29 return vec; 30 } 31 vector<int> mergeSort(vector<int>& vec) 32 {//分解 33 if (vec.empty()) 34 { 35 cerr << "vector's size can't empty" << endl; 36 return vector<int>(); 37 } 38 39 if (1 == vec.size())return vec; 40 auto mid = vec.begin() + vec.size() / 2; 41 vector<int> left(vec.begin(), mid);// 区间:[vec.begin,mid) 42 vector<int> right(mid, vec.end()); 43 left = mergeSort(left); //--原理:不断分解 直到left和right 只有一个元素时,进入mergeArray进行排序 然后返回递归 44 right = mergeSort(right); // 例如:5、64、100000、9845 45 // 第一层 left{5、64},right{100000、9845} 调用 mergeSort(left{5、64})进入第二层 46 // 第二层(left) left_2{5} right_2{64}, 进入 mergeArray排序,返回 new left{5、64}(有顺序)给第一层的left 。 47 // 完成第二层的mergeSort ,回到第一层,这时调用 mergeSort(right{100000,9845}) 进入 right 的第二层 48 // 第二层(right) left_2{100000} right_2{9845} 同理排序完 返回 new right{9845,100000}(有顺序)给第一层的right 49 // 这时第一层 left{5,64} right{9845,100000} 50 // 调用排序 返回 vec{5,64,9845,100000} 51 // 下面的{1, 10, 64, 5,64,100000,98545 },自己推演一下 52 return mergeArray(left, right); 53 }
1 int main() 2 { 3 ifstream in("../data/Pride_and_Prejudice.txt");//为了得到大量测试数字,博主下了本小说,读取小说内容,将字符串转化成数字 4 if (!in) 5 { 6 cerr << "No this file!" << endl; 7 return -1; 8 } 9 string str; 10 uniform_int_distribution<unsigned> u(0, 56011);//数字范围:0~56011 11 while (in >> str) 12 { 13 static default_random_engine e(time(0)); 14 vec.push_back(u(e)); 15 } 16 vec = mergeSort(vec); 17 int i = 0; 18 ofstream out("../data/mergeSort3.txt");//输出到文件中 19 cout << "排好的数列:" << endl; 20 for (auto &u : vec) 21 {//屏幕输出 22 if (i % 10 == 0)cout << endl; 23 cout << u << " "; 24 i++; 25 } 26 out << "排好的数列:" << endl; 27 for (auto &u : vec) 28 {//输出到文件../data/mergeSort3.txt 29 if (i % 10 == 0)out << endl; 30 out << u << " " << flush;//注意flush 不然写入不全 文件操作多flush 31 i++; 32 } 33 cout << "finsh" << endl; 34 getchar(); 35 return 0; 36 }