排序课程设计报告C++Word格式文档下载.docx
《排序课程设计报告C++Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《排序课程设计报告C++Word格式文档下载.docx(37页珍藏版)》请在冰豆网上搜索。
3.程序的主要模块(要求对主要流程图中出现的模块进行说明)
程序的主要模块主要分为主菜单模块和排序算法演示模块。
主菜单
主要功能:
程序运行时,可使运行者根据提醒输入相关操作,从而进入不同的排序方法或者退出。
排序方法及输出
根据运行者对排序的不同选择,进入排序过程
a.直接插入排序:
根据直接排序的算法,输出排序过程
b.折半插入排序:
根据折半插入的算法,输出排序过程
c.冒泡排序:
根据冒泡排序算法,输出排序过程
d.简单选择排序:
根据简单选择排序的算法,输出排序过程
e.快速排序:
根据快速排序的算法,输出排序过程
f.堆排序:
根据堆排序的算法,输出排序过程
g.归并排序:
根据归并排序的算法,输出排序过程
4.程序的主要函数及其伪代码说明
模板类
主要说明程序中用到的类的定义
template<
classtype>
classsortlist
{
private:
intcurrentsize;
//数据表中数据元素的个数
public:
type*arr;
//存储数据元素的向量(排序表)
sortlist():
currentsize(0){arr=newtype[maxsize];
}//构造函数
sortlist(intn){arr=newtype[maxsize];
currentsize=n;
}
voidinsert(inti,typex){arr[i]=x;
~sortlist(){delete[]arr;
}//析构函数
voidswap(type&
x,type&
y)//数据元素x和y交换位置
{typetemp=x;
x=y;
y=temp;
voidbubblesort();
//冒泡排序
voidquicksort(intlow,inthigh);
//快速排序
voidinsertionsort();
//直接插入排序
voidbinaryinsertsort();
//折半插入排序
voidselectsort();
//简单选择排序
voidheapsort();
//堆排序
voidmergesort(sortlist<
type>
&
table);
//归并排序
voidfilterdown(constintstart);
//建立最大堆
voidmergepass(sortlist<
&
sourcetable,sortlist<
mergedtable,constintlen);
//一趟归并
voidmerge(sortlist<
mergedtable,constintleft,constintmid,constintright);
//两路归并算法
};
直接插入排序
直接插入排序的基本思想:
开始时把第一个数据元素作为初始的有序序列,然后从第二个数据元素开始依次把数据元素按关键字大小插入到已排序的部分排序表的适当位置。
当插入第i(1<
i<
=n)个数据元素时,前面的i-1个数据元素已经排好序,这时,用第i个数据元素的关键字与前面的i-1个数据元素的关键字顺序进行比较,找到插入位置后就将第i个数据元素插入。
如此进行n-1次插入,就完成了排序。
以下是在顺序表上实现的直接插入排序
在顺序表上进行直接插入排序时,当插入第i(1<
=n)个数据元素时,前面的arr[0]、arr[1]、…、arr[i-2]已经排好序,这时,用arr[i-1]的关键字依次与arr[i-2],arr[i-3],…的关键字顺序进行比较,如果这些数据元素的关键字大于arr[i-1]的关键字,则将数据元素向后移一个位置,当找到插入位置后就将arr[i-1]插入,就完成了arr[0],arr[1],…,arr[n-1]的排序。
伪代码如下
template<
voidsortlist<
:
insertionsort()
typetemp;
intj;
for(inti=1;
=currentsize-1;
i++)
{
temp=arr[i];
j=i-1;
while(j>
=0&
temp<
arr[j])
{arr[j+1]=arr[j];
j--;
arr[j+1]=temp;
cout<
"
第"
++num<
趟排序结果为:
;
for(intt=0;
t<
currentsize;
t++)
cout<
arr[t]<
"
endl;
}
num=0;
折半插入排序
折半插入排序的基本思想:
设在排序表中有n个数据元素arr[0],arr[1],…,arr[n-1]。
其中,arr[0],arr[1],…,arr[n-1]是已经排好序的部分数据元素序列,在插入arr[i]时,利用折半查找方法寻找arr[i]的插入位置。
折半插入排序方法只能在顺序表存储结构实现。
伪代码如下:
binaryinsertsort()
intleft,right;
{
left=0;
right=i-1;
temp=arr[i];
while(left<
=right)//找插入位置
{
intmid=(left+right)/2;
if(temp<
arr[mid])right=mid-1;
elseleft=mid+1;
}
for(intk=i-1;
k>
=left;
k--)//向后移动
arr[k+1]=arr[k];
arr[left]=temp;
for(intt=0;
cout<
冒泡排序
冒泡排序的基本思想是:
设排序表中有n个数据元素。
首先对排序表中第一,二个数据元素的关键字arr[0]和arr[1]进行比较。
如果前者大于后者,则进行交换;
然后对第二,三个数据做同样的处理;
重复此过程直到处理完最后两个相邻的数据元素。
我们称之为一趟冒泡,它将关键字最大的元素移到排序表的最后一个位置,其他数据元素一般也都向排序的最终位置移动。
然后进行第二趟排序,对排序表中前n-1个元素进行与上述同样的操作,其结果使整个排序表中关键字次大的数据元素被移到arr[n-2]的位置。
如此最多做n-1趟冒泡就能把所有数据元素排好序。
bubblesort()
inti=1;
intfinish=0;
//0表示还没有排好序
while(i<
currentsize&
!
finish)
finish=1;
//排序结束标志置为,假定已经排好序
for(intj=0;
j<
currentsize-i;
j++)
if(arr[j]>
arr[j+1])//逆序
{
swap(arr[j],arr[j+1]);
//相邻元素交换位置
finish=0;
}//排序结束标志置为,表示本趟发生了交换,说明还没有排好序
i++;
for(intt=0;
cout<
5>
简单选择排序(直接选择排序)
直接选择排序的算法基本思想是:
a)开始时设i的初始值为0。
b)如果i<
n-1,在数据元素序列arr[i]arr[n-1]中,选出具有最小关键字的数据元素arr[k];
否则算法结束。
c)若arr[k]不是这组数据元素中的第一个数据元素(i≠k),则将arr[k]与arr[i]这两数据元素的位置对调;
d)令i=i+1转步骤b)。
selectsort()//简单选择排序
intk;
for(inti=0;
k=i;
for(intj=i+1;
if(arr[j]<
arr[k])
k=j;
//k指示当前序列中最小者的位置
if(k!
=i)//最小关键字的数据元素位置不等于i
swap(arr[i],arr[k]);
6>
快速排序
快速排序(QuickSort)又被称做分区交换排序,这是一种平均性能非常好的排序方法。
其算法基本思想是:
任取排序表中的某个数据元素(例如取第一个数据元素)作为基准,按照该数据元素的关键字大小,将整个排序表划分为左右两个子表:
左侧子表中所有数据元素的关键字都小于基准数据元素的关键字。
右侧子表中所有数据元素的关键字都大于或等于基准数据元素的关键字,基准数据元素则排在这两个子表中间(这也是该数据元素最终应安放的位置),然后分别对这两个子表重复施行上述方法的快速排序,直到所有的子表长度为1,则排序结束。
quicksort(intlow,inthigh)//在待排序区间[low,high]上,递归地进行快速排序
inti=low,j=high;
typetemp=arr[low];
//取区间第一个位置为基准位置
if(i<
j)
while(i<
while(i<
j&
arr[j])j--;
if(i<
j){swap(arr[i],arr[j]);
i++;
temp>
=arr[i])i++;
}
arr[i]=temp;
//将基准元素就位
++x<
quicksort(low,i-1);
//在左子区间递归进行快速排序
quicksort(i+1,high);
//在右子区间递归进行快速排序
7>
堆排序(包括建立最大堆和堆排序两个过程)
堆排序算法的基本思想是:
a.对排序表中的数据元素,利用堆的调整算法形成初始堆。
b.输出堆顶元素。
c.对剩余元素重新调整形成堆。
d.重复执行第b、c步,直到所有数据元素被输出。
(1)建立最大堆的伪代码如下:
filterdown(constintstart)
{//向下调整使从start开始到currentsize-1为止的子表成为最大堆
inti=start,j=2*i+1;
//j为i的左孩子
inttablesize=currentsize;
typetemp=arr[i];
while(j<
=currentsize-1)
if(j<
currentsize-1&
arr[j]<
arr[j+1])
j++;
//在两个孩子中选关键字较大者
if(temp>
=arr[j])break;
else{arr[i]=arr[j];
i=j;
j=2*j+1;
arr[i]=temp;
(2)堆排序
如果建立的堆满足最大堆的条件,则堆的第一个数据元素arr[0]具有最大的关键字,将arr[0]与arr[n-1]对调,把具有最大关键字的数据元素交换到最后,再对前面的n-1个数据元素使用堆的调整算法,重新建立最大堆,结果把具有次最大关键字的数据元素又上浮到堆顶,即arr[0]的位置,再对调arr[0]和arr[n-2],…,如此反复执行n-1次,最后得到全部排序好的数据元素序列。
heapsort()
for(inti=(currentsize-2)/2;
i>
=0;
i--)
filterdown(i);
//初始建堆
for(inti=currentsize-1;
=1;
swap(arr[0],arr[i]);
//堆顶元素和最后一个元素交换
currentsize--;
filterdown(0);
//重建最大堆
tablesize;
currentsize=tablesize;
8>
归并排序(包括归并算法,一趟归并算法和归并排序)
1 归并算法
其基本思想是:
设有两个有序表A和B,其数据元素个数(表长)分别为n和m,变量i和j分别是表A和表B的当前检测指针;
设表C是归并后的新有序表,变量k是它的当前存放指针。
开始时i、j、k都分别指向A、B、C三个表的起始位置;
然后根据A[i]与B[j]的关键字的大小,把关键字小的数据元素放到新表C[k]中;
且相应的检测指针(i或j)和存放指针k增加1.如此循环,当i与j中有一个已经超出表长时,将另一个表中的剩余部分照抄到新表C[k]~C[m+n]中。
下面的归并算法中,两个待归并的有序表首尾相接存放在数组sourcetable.arr[]中,其中第一个表的下标范围从left到mid,另一个表的下标范围从mid+1到right。
前一个表中有mid-left+1个数据元素,后一个表中有right–mid个数据元素。
归并后得到的新有序表有right–mid个数据元素。
归并后得到的新有序表存放在另一个辅助数组mergedtable.arr[]中,其下标范围从left到right。
merge(sortlist<
mergedtable,constintleft,constintmid,constintright)
inti=left,j=mid+1,k=left;
//指针初始化
//i是前一段的当前元素位置,j是后一段的当前元素位置,k是辅助数组的当前位置
=mid&
=right)
if(sourcetable.arr[i]<
=sourcetable.arr[j])
{mergedtable.arr[k]=sourcetable.arr[i];
k++;
else{mergedtable.arr[k]=sourcetable.arr[j];
j++;
if(i<
=mid)
for(intp=k,q=i;
q<
=mid;
p++,q++)
mergedtable.arr[p]=sourcetable.arr[q];
//把前一段复制到mergedtable
else
for(intp=k,q=j;
=right;
//把后一段复制到mergedtable
2 一趟归并算法
设数组sourcetable.arr[0]到sourcetable.arr[n-1]中的n个数据元素已经分为一些长度为len的归并项,将这些归并项两两归并,归并成一些长度为2len的归并项,结果放到mergedtable.arr[]中。
如果n不是2len的整数倍,则一趟归并到最后,可能遇到两种情况:
剩下一个长度为len的归并项和一个长度不足len的归并项,可用一次merge算法,将它们归并成一个长度小于2len的归并项。
只剩下一个归并项,其长度小于或等于len,可将它直接复制到数组mergedtable.arr[]中。
mergepass(sortlist<
mergedtable,constintlen)
inti=0;
while(i+2*len<
=currentsize-1)//表示至少有个子序列
merge(sourcetable,mergedtable,i,i+len-1,i+2*len-1);
i+=2*len;
if(i+len<
=currentsize-1)//若只有最后两个子序列
merge(sourcetable,mergedtable,i,i+len-1,currentsize-1);
else//若只有最后一个子序列
for(intj=i;
mergedtable.arr[j]=sourcetable.arr[j];
if(len<
if(num<
currentsize)
mergedtable.arr[t]<
3 归并排序
在一趟归并算法的基础上,实现两路归并排序算法。
在两路归并排序算法中,初始排序表存放在数组table.arr[]中,第一趟归并将table.arr[]中的归并项两两归并,结果存放在辅助数组temptable.arr[]中。
第二趟将temptable.arr[]中的归并项两两归并,结果放回原数组table.arr[]中,如此反复进行。
为了将最后归并结果仍放在数组table.arr[]中,归并趟数应为偶数。
如果做奇数趟就能完成时,最后还需要执行一次一趟归并过程,由于这时的归并项长度len>
=n,因此在则趟归并中while循环不执行,只做把temptable.arr[]中的数据元素复制到table.arr[]的工作。
mergesort(sortlist<
table)
{//按数据元素关键字非递减的顺序对排序表table中数据元素进行递归排序
sortlist<
temptable;
intlen=1;
while(len<
mergepass(table,temptable,len);
len*=2;
mergepass(temptable,table,len);
}
9>
主函数
主要功能是显示主菜单,以及对各种排序的调用
intmain()//主函数
{
cout<
***********************************************************************"
排序问题"
**********************************************************