标签:
这篇文章分两部分来写,第一部分写代码的实现过程,第二部分把实验报告从头到尾呈现出来。
我习惯调试使用的编译器是DEV C++,不是vs系列的,可能头文件上有点区别。但是下面的报告是我放到vs里面测试过的,可以直接用,不影响。
第一部分:(解析)
题目:随机产生一个整型数组,然后用合并排序将该数组做升序排列,要求输出排序前和排序后的数组。
题目分析:
随机产生一个整数数组:这个问题首先想到的是用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[n]; //定义的是动态数组 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[]数组里的数依次输出即可。
第二部分:(实验报告)
(仅供参考!!!!!有误麻烦指出,我会及时修改的。谢谢~)
一、 实验目的
二、 实验内容
随机产生一个整型数组,然后用合并排序将该数组做升序排列,要求输出排序前和排序后的数组。
三、 实验环境
程序设计语言: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[n]; 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、注意通过递归的方式进行拆分。
标签:
原文地址:http://www.cnblogs.com/Amrirey/p/5440788.html