当前位置:文档之家› 分治法实现快速排序与两路合并排序

分治法实现快速排序与两路合并排序

实验报告(2015 / 2016 学年第二学期)课程名称实验名称分治法实现快速排序与两路合并排序实验时间年月日指导单位计算机学院计算机科学与技术系指导教师学生姓名班级学号学院(系) 专业实验报告三、实验原理及内容实验原理:分治法:即分而治之。

将问题分解为规模较小,相互独立,类型相同的问题进行求解。

对于无序数组的有序排序也就是按某种方式将序列分成两个或多个子序列,分别进行排序,再将已排序的子序列合并成一个有序序列。

实验内容:两路合并排序算法的基本思想是:将待排序元素序列一分为二,得到两个长度基本相等的子序列,其过程类似于对半搜索;然后将子序列分别排序,如果子序列较长,还可以继续细分,知道子序列长度不超过1为止。

以上的实现由下列代码执行:void SortableList::MergeSort(){MergeSort(0,n-1);}void SortableList::MergeSort(int left,int right){if (left<right){int mid=(left+right)/2;MergeSort(left,mid);MergeSort(mid+1,right);Merge(left,mid,right);}}函数MergeSort是类SortableList上的公有成员函数。

mid=(left+right)/2;将函数划分为两个长度基本相等的子序列,用递归来执行两个子序列的内部排序。

而Merge函数是将有序的子序列合并,通过合并过程将自问题的解组合成元问题的解。

通过比较两个序列中的最小者,输出其中的较小者,重复此过程,直到一个序列为空,如果还有元素为输出则输出即可。

其中对于Merge函数代码如下:void SortableList::Merge(int left,int mid,int right)//将两个长度之和为n的有序子序列合并一个有序序列{int *temp=new int[right-left+1];int i=left,j=mid+1,k=0;while((i<=mid)&&(j<=right))if (l[i]<=l[j]) temp[k++]=l[i++];else temp[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]上选择一个基准元素(通常是最左边的元素),通过一趟分划操作将序列分成左右两个子序列,左子序列中所有元素都小于等于该基准元素,有子序列中所有元素都大于等于该基准元素。

划分操作如下:int SortableList::Partition(int left,int right){int i=left,j=right+1;do{do i++; while (l[i]<l[left]);do j--; while (l[j]>l[left]);if (i<j) Swap(i,j);}while (i<j);Swap(left,j);return j;}则当前基准元素所在的位置位于左、右子序列的中间,即是其排序完成后的最终位置。

通过递归调用,对左子序列和右子序列再分别进行快速排序算法的调用。

由于每一趟分划结束后,左子序列中的元素均不大于基准元素,右子序列中的元素均不小于基准元素。

而每次分划后,对分划得到的左、右子序列的快速排序又均是就地进行,所以一旦左、右两个子序列都已分别排好序后,无需再执行任何计算,整个序列就是所要求的有序序列了。

因此类中应定义成员函数 QuickSort来完成递归快速排序算法的调用和成员函数。

快速排序操作如下:void SortableList::QuickSort(){QuickSort(0,n-1);}void SortableList::QuickSort(int left,int right){if (left<right){int j=Partition(left,right);QuickSort(left,j-1);QuickSort(j+1,right);}}比较合并排序和快速排序的异同。

合并排序——将序列一分为二即可。

快速排序——需调用 Partition函数将一个序列划分为子序列。

子问题解合并得到原问题解的过程:合并排序——需要调用 Merge函数来实现。

(Merge 函数时间复杂度为O(n))..快速排序——一旦左、右两个子序列都已分别排序,整个序列便自然成为有序序列。

程序中的其他函数:输入输出函数:void SortableList::Input(){for(int i=0;i<maxSize;i++){cin>>l[i];n++;}}void SortableList::Output(){for(int i=0;i<maxSize;i++){cout<<l[i]<<" ";}}主函数:void main(){int n;int i;cout <<"***************************************"<<endl<<endl;cout <<" 1 两路合并排序"<<" "<<"2 快速排序"<< endl<<endl; cout <<"***************************************"<<endl<<endl;while(1){cout <<"************请选择排序方式*************"<<endl;cin>>i;if(i!=1&&i!=2){ cout<<"fault"<<endl;break;}cout <<"*********** 请输入比较个数 ************"<<endl;cin >> n;SortableList l(n);cout<<"************ 请输入"<<n<<"个数:*************"<<endl;l.Input();if(i=1)l.MergeSort();elsel.QuickSort();cout<<"************ 排序后序列是: ***********"<<endl;l.Output();cout<<endl;}}实验结果:实验用例(1)72 26 57 88 42 80 72 48 60(2)0 0 0 0 0完整实验代码:#include<iostream.h>class SortableList{public:SortableList(int mSize)//构造函数{maxSize=mSize;l=new int[maxSize];n=0;}~SortableList()//析构函数{delete []l;}void MergeSort();void QuickSort();void Input();void Output();private:int *l;int maxSize;int n;void MergeSort(int left,int right);void Merge(int left,int mid,int right); void Swap(int i,int j);void QuickSort(int left,int right);int Partition(int left,int right);};void SortableList::Swap(int i,int j) {int c=l[i];l[i]=l[j];l[j]=c;}int SortableList::Partition(int left,int right) {int i=left,j=right+1;do{do i++; while (l[i]<l[left]);do j--; while (l[j]>l[left]);if (i<j) Swap(i,j);}while (i<j);Swap(left,j);return j;}void SortableList::QuickSort(){QuickSort(0,n-1);}void SortableList::QuickSort(int left,int right) {if (left<right){int j=Partition(left,right);QuickSort(left,j-1);QuickSort(j+1,right);}}void SortableList::MergeSort(){MergeSort(0,n-1);}void SortableList::MergeSort(int left,int right) {if (left<right){int mid=(left+right)/2;MergeSort(left,mid);MergeSort(mid+1,right);Merge(left,mid,right);}}void SortableList::Merge(int left,int mid,int right)//将两个长度之和为n的有序子序列合并一个有序序列{int *temp=new int[right-left+1];int i=left,j=mid+1,k=0;while((i<=mid)&&(j<=right))if (l[i]<=l[j]) temp[k++]=l[i++];else temp[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++];}void SortableList::Input(){for(int i=0;i<maxSize;i++){cin>>l[i];n++;}}void SortableList::Output(){for(int i=0;i<maxSize;i++){cout<<l[i]<<" ";}}void main(){int n;int i;cout <<"***************************************"<<endl<<endl;cout <<" 1 两路合并排序"<<" "<<"2 快速排序"<< endl<<endl; cout <<"***************************************"<<endl<<endl;while(1){cout <<"************请选择排序方式*************"<<endl;cin>>i;if(i!=1&&i!=2){ cout<<"fault"<<endl;break;}cout <<"*********** 请输入比较个数 ************"<<endl;cin >> n;SortableList l(n);cout<<"************ 请输入"<<n<<"个数:*************"<<endl;l.Input();if(i=1)l.MergeSort();elsel.QuickSort();cout<<"************ 排序后序列是: ***********"<<endl;l.Output();cout<<endl;}}实验报告。

相关主题