您的位置:首页 > 编程语言 > C语言/C++

算法实验:分治法合并排序(C++)

2016-04-27 22:48 169 查看

  这篇文章分两部分来写,第一部分写代码的实现过程,第二部分把实验报告从头到尾呈现出来。

  我习惯调试使用的编译器是DEV C++,不是vs系列的,可能头文件上有点区别。但是下面的报告是我放到vs里面测试过的,可以直接用,不影响。

 

第一部分:(解析)

  题目:随机产生一个整型数组,然后用合并排序将该数组做升序排列,要求输出排序前和排序后的数组。

 

题目分析:

  1. 需要随机产生一个整数数组;
  2. 采用的算法是合并排序,也就是用归并排序;
  3. 输出排序后的数组。

 

  随机产生一个整数数组:这个问题首先想到的是用rand()函数(c语言和c++我记得好像不太一样,c++是用rand()函数),rand()函数不需要参数,是来返回一个从0到最大随机数的任意整数,最大随机数的大小通常是固定的一个大整数。写法格式是这样的:

1 #include<cstdlib>    //使用rand()函数必要的头文件
2
3  //获取a~b之间的一个随机数可以表示为:
4  a + rand() % n    //a是起始值,n是整数的范围
5  //或者
6  a + rand() % (b-a+1)    // a是起始值,b是最大值
7  //如果要0~1之间的小数,可以先取得0~10的整数,然后除以10就可以得到随机到十分位的随机小数,百分位、千分位同理。

 

  然后rand()函数会涉及到用time.h.头文件,使用srand(time(0))来获取当前时间,使随机数发生器随机化这些内容,这里就不探讨了,主要解决掉问题是能把某一个数到另一个数的随机数产生即可,代码如下:

 

1 int n;
2 cout << "输入产生的数组个数:";
3 cin >> n;
4 cout << endl;
5
6 int *Array = new int
;    //定义的是动态数组
7 cout << "产生的随机数组为:";
8
9 for (int i = 0; i < n; i++) {
10     Array[i] =  (rand()%(100-0+1))+0;    //产生0-100的整数
11     cout<<Array[i]<<"  ";    //产生后一个一个输出来
12 }
13 cout<<endl;

 

  归并排序:百度很多博客都在详细介绍归并,这里简单说明一下:先把已知数组分成两组,然后两组中分别再分成两组,直到每一组都只有一个数据,然后再合并的同时排序,直到都合并起来就ok。需要写出两个函数:

  MergeSort() —>归并函数,用递归的方式把数据细分,最后合并。

  Merge() —>合并函数。

 

代码如下:

1 //合并函数
2 void Merge(int *_Array, int p, int q, int r) {// p:第0个;r:第n-1个数,q:第(r + p) / 2个数
3     int len1 = q - p + 1;
4     int len2 = r - q;
5     int *L = new int[len1 + 1];//用动态数组储存左边的数
6     int *R = new int[len2 + 1];//用动态数组储存右边的数
7
8     for (int i = 0; i < len1; i++) {// 把Array数组左边的数放入L数组
9         L[i] = _Array[p + i];
10     }
11
12     for (int j = 0; j < len2; j++) {// 把Array数组右边的数放入R数组
13         R[j] = _Array[q + 1 + j];
14     }
15     L[len1]=R[len2]=INT_MAX;    //定义无穷大
16     int i = 0, j = 0;
17     for (int k = p; k <= r; k++) {
18         if (L[i] < R[j]) {//小的放左边,大的放右边
19             _Array[k] = L[i];
20             i++;
21         }
22         else {
23             _Array[k] = R[j];
24             j++;
25         }
26     }
27 }

 

1 //  归并排序
2 void MergeSort(int _Array[], int p, int r) {
3     if (p < r) {//p:第0个;r:第n-1个数。数组至少要有两个数据
4         int q;
5         q = (r + p) / 2;//拆分两组
6         MergeSort(_Array , p , q);//拆分第0个到第 (r + p) / 2个 ,即拆分左半部分
7         MergeSort(_Array , q+1 , r);//拆分第(r + p) / 2个到第r个 ,即拆分右半部分
8         Merge(_Array , p , q , r);//调用合并函数,从第0个到第n-1个排好
9     }
10 }

 

 

  输出排序后的数组:调用MergeSort()函数后直接在主函数中用for循环把Array[]数组里的数依次输出即可。

 

第二部分:(实验报告)

(仅供参考!!!!!有误麻烦指出,我会及时修改的。谢谢~)

 

实验一 分治法合并排序

一、        实验目的

  1. 掌握合并排序的基本思想。
  2. 掌握合并排序的实现方法。
  3. 学会分析算法的时间复杂度。
  4. 学会用分治法解决实际问题。

 

二、        实验内容

随机产生一个整型数组,然后用合并排序将该数组做升序排列,要求输出排序前和排序后的数组。

 

三、        实验环境

程序设计语言:c++

编程工具:microsoft visual studio 2010

 

四、        程序代码

 

1 #include <stdafx.h>
2 #include "iostream"
3 #include "time.h"
4 #include "stdlib.h"
5 using namespace std;
6 //合并函数
7 void Merge(int *_Array, int p, int q, int r) {// p:第0个;r:第n-1个数,q:第(r + p) / 2个数
8     int len1 = q - p + 1;
9     int len2 = r - q;
10     int *L = new int[len1 + 1];//用动态数组储存左边的数
11     int *R = new int[len2 + 1];//用动态数组储存右边的数
12
13     for (int i = 0; i < len1; i++) {// 把Array数组左边的数放入L数组
14         L[i] = _Array[p + i];
15     }
16
17     for (int j = 0; j < len2; j++) {// 把Array数组右边的数放入R数组
18         R[j] = _Array[q + 1 + j];
19     }
20     L[len1]=R[len2]=INT_MAX;    //定义无穷大
21     int i = 0, j = 0;
22     for (int k = p; k <= r; k++) {
23         if (L[i] < R[j]) {//小的放左边,大的放右边
24             _Array[k] = L[i];
25             i++;
26         }
27         else {
28             _Array[k] = R[j];
29             j++;
30         }
31     }
32 }
33 //  归并排序
34 void MergeSort(int _Array[], int p, int r) {
35     if (p < r) {//p:第0个;r:第n-1个数。数组至少要有两个数据
36         int q;
37         q = (r + p) / 2;//拆分两组
38         MergeSort(_Array , p , q);//拆分第0个到第 (r + p) / 2个 ,即拆分左半部分
39         MergeSort(_Array , q+1 , r);//拆分第(r + p) / 2个到第r个 ,即拆分右半部分
40         Merge(_Array , p , q , r);//调用合并函数,从第0个到第n-1个排好
41     }
42 }
43
44 int main() {
45     int n;
46     cout << "输入产生的数组个数:";
47     cin >> n;
48     cout << endl;
49     int *Array = new int
;
50     cout << "产生的随机数组为:";
51     srand((unsigned)time(0));
52
53     for (int i = 0; i < n; i++) {
54         Array[i] =  (rand()%(100-0+1))+0;
55         //cin>>;
56         cout<<Array[i]<<"  ";
57     }
58     cout<<endl;
59
60     MergeSort(Array,0,n-1);
61
62     cout << "排序后的数组为:";
63     for(int j  = 0;j<n;j++){
64         cout<<Array[j]<<"  ";
65     }
66 //    int a;
67 //    cin>>a;
68     return 0 ;
69 }

 

五、        实验结果截图

 

 

六、        实验总结

1、通过本次实验学到了分治算法,分治法的设计思想是:将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。

2、二路归并排序主要思路是按照将一组数据不断二次拆分,直到拆分成每组数据只有一个数,最后相邻的数合并起来为一组数,认为它是一组有序的数。

3、注意通过递归的方式进行拆分。

转载于:https://www.cnblogs.com/Amrirey/p/5440788.html

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: