分治法实现快速排序与两路合并排序_第1页
分治法实现快速排序与两路合并排序_第2页
分治法实现快速排序与两路合并排序_第3页
分治法实现快速排序与两路合并排序_第4页
分治法实现快速排序与两路合并排序_第5页
已阅读5页,还剩7页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

实验报告(2015/2016学年第二学期)课程名称实验名称 分治法实现快速排序与两路合并排序实验时间 年 月 日指导单位 十算机科学与技术系指导教师学生姓名 班级学号学院(系) 专业实验报告

实验名称分治法指导教师实验类型验证 实验学时 2实验时间一、实验目的和要求实验目的:理解分治法的算法思想,阅读实现书上已有的部分程序代码并完善程序,加深对分治法的算法原理及实现过程的理解。实验要求:用分治法实现一组无序序列的两路合并排序和快速排序。要求清楚合并排序及快速排序的基本原理,编程实现分别用这两种方法将输入的一组无序序列排序为有序序列后输出。二、实验环境(实验设备)硬件:微型计算机软件:Windows操作系统、MicrosoftVisualC++6.0三、实验原理及内容实验原理:分治法:即分而治之。将问题分解为规模较小,相互独立,类型相同的问题进行求解。对于无序数组的有序排序也就是按某种方式将序列分成两个或多个子序列,分别进行排序,再将已排序的子序列合并成一个有序序列。实验内容:两路合并排序算法的基本思想是:将待排序元素序列一分为二,得到两个长度基本相等的子序列,其过程类似于对半搜索;然后将子序列分别排序,如果子序列较长,还可以继续细分,知道子序列长度不超过1为止。以上的实现由下列代码执行:voidSortableList::MergeSort(){MergeSort(0,n-1);}voidSortableList::MergeSort(intleft,intright){if(left<right){intmid=(left+right)/2;MergeSort(left,mid);MergeSort(mid+1,right);Merge(left,mid,right);}}函数MergeSort是类SortableList上的公有成员函数。mid=(left+right)/2;将函数划分为两个长度基本相等的子序列,用递归来执行两个子序列的内部排序。而Merge函数是将有序的子序列合并,通过合并过程将自问题的解组合成元问题的解。通过比较两个序列中的最小者,输出其中的较小者,重复此过程,直到一个序列为空,如果还有元素为输出则输出即可。其中对于Merge函数代码如下:voidSortableList::Merge(intleft,intmid,intright)//将两个长度之和为n的有序子序列合并一个有序序列{int*temp=newint[right-left+1];inti=left,j二mid+1,k=0;while((i〈二mid)&&(j<=right))if(l[i]<=l[j])temp[k++]=l[i++];elsetemp[k++]=l[j++];while(i<=mid)temp[k++]=l[i++];while(j<=right)temp[k++]=l[j++];for(i=0,k=left;k<=right;)l[k++]二temp[i++];}快速排序算法的基本思想是:在待排序序列K[left:right]上选择一个基准元素(通常是最左边的元素),通过一趟分划操作将序列分成左右两个子序列,左子序列中所有元素都小于等于该基准元素,有子序列中所有元素都大于等于该基准元素。划分操作如下:intSortableList::Partition(intleft,intright){inti=left,j二right+1;do{doi++;while(l[i]<l[left]);doj--;while(l[j]>l[left]);if(i<j)Swap(i,j);}while(i<j);Swap(left,j);returnj;}则当前基准元素所在的位置位于左、右子序列的中间,即是其排序完成后的最终位置。通过递归调用,对左子序列和右子序列再分别进行快速排序算法的调用。由于每一趟分划结束后,左子序列中的元素均不大于基准元素,右子序列中的元素均不小于基准元素。而每次分划后,对分划得到的左、右子序列的快速排序又均是就地进行,所以一旦左、右两个子序列都已分别排好序后,无需再执行任何计算,整个序列就是所要求的有序序列了。因此类中应定义成员函数QuickSort来完成递归快速排序算法的调用和成员函数。快速排序操作如下:voidSortableList::QuickSort(){QuickSort(0,n-l);}voidSortableList::QuickSort(intleft,intright){if(left<right){intj二Partition(left,right);QuickSort(left,j-l);QuickSort(j+1,right);}}比较合并排序和快速排序的异同。合并排序一一将序列一分为二即可。快速排序——需调用Partition函数将一个序列划分为子序列。子问题解合并得到原问题解的过程:合并排序一一需要调用Merge函数来实现。(Merge函数时间复杂度为O(n))..快速排序一一一旦左、右两个子序列都已分别排序,整个序列便自然成为有序序列。程序中的其他函数:输入输出函数:voidSortableList::Input(){for(inti=O;i<maxSize;i++){cin>>l[i];n++;}}voidSortableList::0utput(){for(inti=O;i<maxSize;i++){cout<<l[i]<<"";}}主函数:voidmain(){intn;inti;cout<<"***************************************"<<endl<<endl;cout<<" 1两路合并排序"<<" "<<"2快速排序"<<endl<<endl;cout<<"***************************************"<<endl<<endl;while(l){cout<<"************请选择排序方式*************"<<endl;cin>>i;if(i!=l&&i!=2){cout<<"fault"<<endl;break;}cout<<"***********请输入比较个数************"<<endl;cin>>n;SortableListl(n);cout<<"************请输入"<<n<〈"个数:*************"<<endl;l.Input();if(i=1)l.MergeSort();elsel.QuickSort();cout<<"************排序后序列是:***********"<<endl;l.0utput();cout<<endl;}}实验结果:实验用例(1)722657884280724860(2)00000

完整实验代码:#include<iostream.h>classSortableList{public:SortableList(intmSize)//构造函数{maxSize二mSize;l二newint[maxSize];n=0;}~SortableList()//析构函数{delete[]l;}voidMergeSort();voidQuickSort();voidInput();voidOutput();private:int*l;intmaxSize;intn;voidMergeSort(intleft,intright);voidMerge(intleft,intmid,intright);voidSwap(inti,intj);voidQuickSort(intleft,intright);intPartition(intleft,intright);};voidSortableList::Swap(inti,intj){intc=l[i];l[i]=l[j];l[j]=c;}intSortableList::Partition(intleft,intright){inti=left,j二right+1;do{doi++;while(l[i]<l[left]);doj--;while(l[j]>l[left]);if(i<j)Swap(i,j);}while(i<j);Swap(left,j);returnj;}voidSortableList::QuickSort(){QuickSort(0,n-l);}voidSortableList::QuickSort(intleft,intright){if(left<right){intj=Partition(left,right);QuickSort(left,j-l);QuickSort(j+1,right);}}voidSortableList::MergeSort(){MergeSort(0,n-l);}voidSortableList::MergeSort(intleft,intright){if(left<right){intmid=(left+right)/2;MergeSort(left,mid);MergeSort(mid+1,right);Merge(left,mid,right);}}voidSortableList::Merge(intleft,intmid,intright)//将两个长度之和为n的有序子序列合并一个有序序列{int*temp=newint[right-left+1];inti=left,j二mid+l,k=0;while((i<=mid)&&(j〈二right))if(l[i]<=l[j])temp[k++]=l[i++];elsetemp[k++]=l[j++];while(i<=mid)temp[k++]=l[i++];while(j<=right)temp[k++]=l[j++];for(i=0,k=left;k〈二right;)l[k++]二temp[i++];}voidSortableList::Input(){for(inti=O;i<maxSize;i++){cin>>l[i];n++;}}voidSortableList::0utput(){for(inti=O;i<maxSize;i++){cout<<l[i]<<"";}}voidmain(){intn;inti;cout<<"***************************************"<<endl<<endl;cout<<" 1两路合并排序"<<" "<<"2快速排序"<<endl<<endl;cout<<"***************************************"<<endl<<endl;while(l){cout<<"************请选择排序方式*************"<<endl;cin>>i;if(i!=l&&i!=2){cout<<"fault"<<endl;break;}cout<<"***********请输入比较个数************"<<endl;cin>>n;SortableListl(n);cout<<"******

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论