归并排序(用容器实现)

基础排序算法之: 归并排序

  • 思想:

归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(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 }

转载请注明:http://www.cnblogs.com/firstcxj/

 

posted @ 2015-06-10 16:46  ChessChan  阅读(231)  评论(0编辑  收藏  举报