分治法实现一组无序序列的两路合并排序和快速排序Word文件下载.docx
《分治法实现一组无序序列的两路合并排序和快速排序Word文件下载.docx》由会员分享,可在线阅读,更多相关《分治法实现一组无序序列的两路合并排序和快速排序Word文件下载.docx(9页珍藏版)》请在冰豆网上搜索。
专业
实验类型
验证
实验学时
2
一、实验目的和任务
理解分治法的算法思想,阅读实现书上已有的部分程序代码并完善程序,加深对分治法的算法原理及实现过程的理解。
用分治法实现一组无序序列的两路合并排序和快速排序。
要求清楚合并排序及快速排序的基本原理,编程实现分别用这两种方法将输入的一组无序序列排序为有序序列后输出。
二、实验环境(实验设备)
VC++6.0
三、实验原理及内容(包括操作过程、结果分析等)
实验原理
1、排序是数据处理中常用的重要手段,是指将一个元素序列调整为按指定关键字值的递增(或递减)次序排列的有序序列。
用分治法求解排序问题的思路是,按某种方式将序列分成两个或多个子序列,分别进行排序,再将已排序的子序列合并成一个有序序列。
合并排序和快速排序是两种典型的符合分治策略的排序算法。
2、如果采用顺序存储的可排序表作为算法实现的数据结构,则需要定义一个可排序表类SortableList,两路合并算法和快速排序算法均由定义在该类上的函数实现。
其中Input函数和Output函数分别用于向可排序表中输入待排序序列,以及输出已经
排序好的序列。
3、两路合并排序算法的基本思想是:
将待排序元素平分成大小大致相同的两个子序列,然后对每个子序列分别使用递归的方法进行两路合并排序,直到子序列长度变为1,最后利用合并算法将得到的已排序好的两个子序列合并成一个有序的序列。
两路合并排序算法的核心部分是将子问题的解组合成原问题解得合并操作。
常用的操作是新建一个序列,序列的大小等于要合并的两个子序列的长度之和。
比较两个子序列中的最小值,输出其中较小者到新建的序列中,重复此过程直到其中一个子序列为空。
如果另一个子序列中还有元素未输出,则将剩余元素依次输出到新建序列中即可。
最终得到一个有序序列。
4、结合书上已有的程序代码,使用分治法的快速排序算法,实现对初始序列的排序。
快速排序算法的基本思想是:
(1)在待排序序列K[left:
right]上选择一个基准元素(通常是最左边的元素Kleft),通过一趟分划操作将序列分成左右两个子序列,左子序列中所有元素都小于等于该基准元素,有子序列中所有元素都大于等于该基准元素。
则当前基准元素所在的位置位于左、右子序列的中间,即是其排序完成后的最终位置。
(2)通过递归调用,对左子序列和右子序列再分别进行快速排序算法的调用。
(3)由于每一趟分划结束后,左子序列中的元素均不大于基准元素,右子序列中的元素均不小于基准元素。
而每次分划后,对分划得到的左、右子序列的快速排序又均是就地进行,所以一旦左、右两个子序列都已分别排好序后,无需再执行任何计算,整个序列就是所要求的有序序列了。
因此类中应定义成员函数QuickSort来完成递归快速排序算法的调用和成员函数
5、比较合并排序和两种算法的异同。
问题分解过程:
合并排序——将序列一分为二即可。
(十分简单)快速排序——需调用Partition函数将一个序列划分为子序列。
(分解方法相对较困难)子问题解合并得到原问题解的过程:
合并排序——需要调用Merge函数来实现。
(Merge函数时间复杂度为O(n))..快速排序——一旦左、右两个子序列都已分别排序,整个序列便自然成为有序序列。
(异常简单,几乎无须额外的工作,省去了从子问题解合并得到原问题解的过程)
基本程序
(一)两路合并排序
#include<
iostream.h>
classSortableList{
public:
SortableList(intmSize){
maxSize=mSize;
l=newint[maxSize];
n=0;
}
~SortableList(){
delete[]l;
voidMergeSort();
voidInput();
voidOutput();
private:
int*l;
intmaxSize;
intn;
voidMergeSort(intleft,intright);
voidMerge(intleft,intmid,intright);
};
voidSortableList:
:
MergeSort(){
MergeSort(0,n-1);
MergeSort(intleft,intright){
if(left<
right){
intmid=(left+right)/2;
MergeSort(left,mid);
MergeSort(mid+1,right);
Merge(left,mid,right);
Merge(intleft,intmid,intright){
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++];
voidSortableList:
Input(){
for(inti=0;
i<
maxSize;
i++){
cin>
>
l[i];
n++;
}
Output(){
cout<
<
l[i]<
"
"
;
endl;
voidmain(){
SortableListl(10);
请输入10个数:
l.Input();
l.MergeSort();
l.Output();
(二)快速排序
classSortableList
{
public:
voidQuickSort();
private:
voidSi,intj);
voidQuickSort(intleft,intright);
intPartition(intleft,intright);
Si,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]>
if(i<
j)S);
}while(i<
j);
S);
returnj;
QuickSort()
QuickSort(0,n-1);
QuickSort(intleft,intright)
if(left<
intj=Partition(left,right);
QuickSort(left,j-1);
QuickSort(j+1,right);
SortableListx(10);
x.Input();
x.QuickSort();
x.Output();
实验结果
两路合并排序
快速排序
四、实验小结(包括问题和解决方法、心得体会等)
五、指导教师评语
成绩
批阅人
日期