数据结构课程设报告各种排序算法的比较.docx

上传人:b****8 文档编号:28904911 上传时间:2023-07-20 格式:DOCX 页数:33 大小:431.67KB
下载 相关 举报
数据结构课程设报告各种排序算法的比较.docx_第1页
第1页 / 共33页
数据结构课程设报告各种排序算法的比较.docx_第2页
第2页 / 共33页
数据结构课程设报告各种排序算法的比较.docx_第3页
第3页 / 共33页
数据结构课程设报告各种排序算法的比较.docx_第4页
第4页 / 共33页
数据结构课程设报告各种排序算法的比较.docx_第5页
第5页 / 共33页
点击查看更多>>
下载资源
资源描述

数据结构课程设报告各种排序算法的比较.docx

《数据结构课程设报告各种排序算法的比较.docx》由会员分享,可在线阅读,更多相关《数据结构课程设报告各种排序算法的比较.docx(33页珍藏版)》请在冰豆网上搜索。

数据结构课程设报告各种排序算法的比较.docx

数据结构课程设报告各种排序算法的比较

数据结构课程设计报告

几种排序算法的演示

一、需求分析:

1、运行环境:

MicrosoftVisualStudio2005

2、程序实现功能:

通过用户键入的数据,经过程序进行排序,最后给予数据由小到大的输出。

排序的方式包含教材中所介绍的几种常用的排序方式:

直接插入排序、折半插入排序、冒泡排序、快速排序、选择排序、堆排序、归并排序。

每种排序过程中均显示每一趟排序的细节。

3、程序的输入:

输入所需排序方式的序号。

输入排序的数据的个数。

输入具体的数据元素。

4、程序的输出:

输出排序每一趟的结果,及最后排序结果

二、设计说明:

1、算法设计思想:

a交换排序(冒泡排序、快速排序)

交换排序的基本思想是:

对排序表中的数据元素按关键字进行两两比较,如果发生逆序(即排列顺序与排序后的次序正好相反),则两者交换位置,直到所有数据元素都排好序为止。

b插入排序(直接插入排序、折半插入排序)

插入排序的基本思想是:

每一次设法把一个数据元素插入到已经排序的部分序列的合适位置,使得插入后的序列仍然是有序的。

开始时建立一个初始的有序序列,它只包含一个数据元素。

然后,从这个初始序列出发不断插入数据元素,直到最后一个数据元素插到有序序列后,整个排序工作就完成了。

c选择排序(简单选择排序、堆排序)

选择排序的基本思想是:

第一趟在有n个数据元素的排序表中选出关键字最小的数据元素,然后在剩下的n-1个数据元素中再选出关键字最小(整个数据表中次小)的数据元素,依次重复,每一趟(例如第i趟,i=1,…,n-1)总是在当前剩下的n-i+1个待排序数据元素中选出关键字最小的数据元素,作为有序数据元素序列的第i个数据元素。

等到第n-1趟选择结束,待排序数据元素仅剩下一个时就不用再选了,按选出的先后次序所得到的数据元素序列即为有序序列,排序即告完成。

d归并排序(两路归并排序)

两路归并排序的基本思想是:

假设初始排序表有n个数据元素,首先把它看成是长度为1的首尾相接的n个有序子表(以后称它们为归并项),先做两两归并,得n/2上取整个长度为2的归并项(如果n为奇数,则最后一个归并项的长度为1);再做两两归并,……,如此重复,最后得到一个长度为n的有序序列。

1、主要的数据结构设计说明:

程序的数据结构为:

堆、线性表;

2、程序的主要流程图:

 

3、程序的主要模块,

A主菜单

B排序模块:

a直接插入排序

b折半插入排序

c冒泡排序

d快速排序

e简单选择排序

f堆排序

g归并排序

4、程序的主要函数及其伪代码

a模板类

templateclasssortlist

{

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;}

voidinsertionsort();//直接插入排序

voidbinaryinsertsort();//折半插入排序

voidbubblesort();//冒泡排序

voidselectsort();//简单选择排序

voidquicksort(intlow,inthigh);//快速排序

voidheapsort();//堆排序

voidmergesort(sortlist&table);//归并排序

voidfilterdown(constintstart);//建立最大堆

voidmergepass(sortlist&sourcetable,sortlist&mergedtable,constintlen);//一趟归并

voidmerge(sortlist&sourcetable,sortlist&mergedtable,constintleft,constintmid,constintright);//两路归并算法

}

b直接插入排序

template//直接插入排序

voidsortlist:

:

insertionsort()

{

template//直接插入排序

voidsortlist:

:

insertionsort()

{

typetemp;

intj;

for(inti=1;i<=currentsize-1;i++)

{

temp=arr[i];j=i-1;

while(j>=0&&temp

{arr[j+1]=arr[j];j--;}

arr[j+1]=temp;

cout<<"第"<<++num<<"趟排序结果为:

";

for(intt=0;t

cout<

cout<

}

num=0;

}

c折半插入排序:

template//折半插入排序

voidsortlist:

:

binaryinsertsort()

{

typetemp;

intleft,right;

for(inti=1;i

{

left=0;right=i-1;temp=arr[i];

while(left<=right)//找插入位置

{

intmid=(left+right)/2;

if(temp

elseleft=mid+1;

}

for(intk=i-1;k>=left;k--)//向后移动

arr[k+1]=arr[k];

arr[left]=temp;

cout<<"第"<<++num<<"趟排序结果为:

";

for(intt=0;t

cout<

cout<

}

num=0;

}

d冒泡排序

template//冒泡排序

voidsortlist:

:

bubblesort()

{

inti=1;

intfinish=0;//0表示还没有排好序

while(i

finish)

{

finish=1;//排序结束标志置为,假定已经排好序

for(intj=0;j

if(arr[j]>arr[j+1])//逆序

{

swap(arr[j],arr[j+1]);//相邻元素交换位置

finish=0;

}//排序结束标志置为,表示本趟发生了交换,说明还没有排好序

i++;

cout<<"第"<<++num<<"趟排序结果为:

";

for(intt=0;t

cout<

cout<

}

num=0;

}

e简单选择排序

template

voidsortlist:

:

selectsort()//简单选择排序

{

intk;

for(inti=0;i<=currentsize-1;i++)

{

k=i;

for(intj=i+1;j

if(arr[j]

k=j;//k指示当前序列中最小者的位置

if(k!

=i)//最小关键字的数据元素位置不等于i

swap(arr[i],arr[k]);

cout<<"第"<<++num<<"趟排序结果为:

";

for(intt=0;t

cout<

cout<

}

num=0;

}

f快速排序:

template//快速排序

voidsortlist:

:

quicksort(intlow,inthigh)//在待排序区间[low,high]上,递归地进行快速排序

{

inti=low,j=high;

typetemp=arr[low];//取区间第一个位置为基准位置

if(i

{

while(i

{

while(i

if(i

while(i=arr[i])i++;

if(i

}

arr[i]=temp;//将基准元素就位

cout<<"第"<<++x<<"趟排序结果为:

";

for(intt=0;t

cout<

cout<

quicksort(low,i-1);//在左子区间递归进行快速排序

quicksort(i+1,high);//在右子区间递归进行快速排序

}

}

g堆排序

(1)建立最大堆的伪代码如下:

template//建立最大堆

voidsortlist:

:

filterdown(constintstart)

{//向下调整使从start开始到currentsize-1为止的子表成为最大堆

inti=start,j=2*i+1;//j为i的左孩子

inttablesize=currentsize;

typetemp=arr[i];

while(j<=currentsize-1)

{

if(j

j++;//在两个孩子中选关键字较大者

if(temp>=arr[j])break;

else{arr[i]=arr[j];i=j;j=2*j+1;

}

}

arr[i]=temp;

}

(2)堆排序

template//堆排序

voidsortlist:

:

heapsort()

{

inttablesize=currentsize;

for(inti=(currentsize-2)/2;i>=0;i--)

filterdown(i);//初始建堆

for(inti=currentsize-1;i>=1;i--)

{

swap(arr[0],arr[i]);//堆顶元素和最后一个元素交换

currentsize--;

filterdown(0);//重建最大堆

cout<<"第"<<++num<<"趟排序结果为:

";

for(intt=0;t

cout<

cout<

}

num=0;

currentsize=tablesize;

}

h归并排序

归并算法:

template

voidsortlist:

:

merge(sortlist&sourcetable,sortlist&mergedtable,constintleft,constintmid,constintright)

{

inti=left,j=mid+1,k=left;//指针初始化

//i是前一段的当前元素位置,j是后一段的当前元素位置,k是辅助数组的当前位置

while(i<=mid&&j<=right)

if(sourcetable.arr[i]<=sourcetable.arr[j])

{mergedtable.arr[k]=sourcetable.arr[i];i++;k++;}

else{mergedtable.arr[k]=sourcetable.arr[j];j++;k++;}

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;q<=right;p++,q++)

mergedtable.arr[p]=sourcetable.arr[q];//把后一段复制到mergedtable

}

一趟归并算法

template

template

voidsortlist:

:

mergepass(sortlist&sourcetable,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;j<=currentsize-1;j++)

mergedtable.arr[j]=sourcetable.arr[j];

if(len<=currentsize-1)

{

if(num

{

cout<<"第"<<++num<<"趟排序结果为:

";

for(intt=0;t

cout<

cout<

}

}

}

归并排序:

template

voidsortlist:

:

mergesort(sortlist&table)

{//按数据元素关键字非递减的顺序对排序表table中数据元素进行递归排序

sortlisttemptable;

intlen=1;

while(len

{

mergepass(table,temptable,len);len*=2;

mergepass(temptable,table,len);len*=2;

}

num=0;

}

i主函数

intmain()//主函数

{intc=1;

charch,cc;

intn1=0;

while(c!

=0)

{

cout<<"███████████████请选择排序的方法███████████████"<

cout<<"1直接插入排序2折半插入排序"<

cout<<"3冒泡排序4简单选择排序"<

cout<<"5快速排序6堆排序"<

cout<<"7归并排序0退出排序程序"<

cout<<"██████████████████████████████████████"<

cout<<"\n请输入您需要的排序种类(键入对应的代号):

";

cin>>ch;

if(ch=='0'){cout<<"您已成功退出该系统!

"<

if(ch>='0'&&ch<='7')

{cout<<"\n请输入所需排序的个数:

";

cin>>n;

cout<<"\n请输入"<

";

sortlisttable(n);

for(inti=0;i

{cin>>number;table.insert(i,number);}

switch(ch)

{

case'1':

cout<<"\n███████您选择的是直接插入排序███████\n"<

table.insertionsort();

break;

system("pause");

break;

case'2':

cout<<"\n███████您选择的是折半插入排序███████\n"<

table.binaryinsertsort();

break;

system("pause");

break;

case'3':

cout<<"\n███████您选择的是冒泡排序███████\n"<

table.bubblesort();

break;

system("pause");

break;

case'4':

cout<<"\n███████您选择的是简单选择排序███████\n"<

table.selectsort();

break;

system("pause");

break;

case'5':

cout<<"\n███████您选择的是快速排序███████\n"<

table.quicksort(0,n-1);

break;

system("pause");

break;

case'6':

cout<<"\n███████您选择的是堆排序███████\n"<

table.heapsort();

break;

system("pause");

break;

case'7':

cout<<"\n███████您选择的是归并排序███████\n"<

table.mergesort(table);

break;

system("pause");

break;

}

}

}

system("pause");

return0;

}

三、上机结果及体会:

a.程序的性能分析,时空分析:

直接插入排序(稳定的排序方法)

1时间复杂度

a)若待排序记录按关键字从小到大排列(正序)

关键字比较次数:

记录移动次数:

2(n-1)

b)若待排序记录按关键字从大到小排列(逆序)

关键字比较次数:

 

记录移动次数:

c)若待排序记录是随机的,取最好和最坏情况的平均值

关键字比较次数(约为):

记录移动次数(约为):

2空间复杂度:

S(n)=O

(1)

b.折半插入排序(稳定的排序算法)

就平均性能而言,因为折半查找优于顺序查找,所以折半插入排序也优于直接插入排序。

关键字的比较次数为:

n*log2(n)

c.冒泡排序(稳定的排序算法)

1.时间复杂度:

a)最好情况(正序)

b)比较次数:

n-1(只要进行一趟即可)

c)移动次数:

0

d)最坏情况(逆序)

e)比较次数:

(需n-1趟,每趟达到最大比较次数)

f)移动次数:

在最坏情况下,时间复杂度为:

T(n)=O(n²)

2.空间复杂度:

S(n)=O

(1)

d.简单选择排序(不稳定的排序方法)

1.时间复杂度:

O(n2)。

2.空间复杂度:

S

(1)。

e.快速排序(不稳定的排序方法)

1.时间复杂度

最好情况(每次总是选到中间值作枢轴)T(n)=O(nlog2n)

最坏情况(每次总是选到最小或最大元素作枢轴)T(n)=O(n²)

2.空间复杂度:

需栈空间以实现递归

最坏情况:

S(n)=O(n)

一般情况:

S(n)=O(log2n)

f.堆排序(不稳定的排序方法)]

1.间复杂性为O(nlog2n)。

2空间复杂性为O

(1)。

g.归并排序(稳定的排序方法)

1时间复杂度为O(nlog2n)。

2空间复杂度为O(n)。

1、程序运行时的初值和运行结果,

主菜单:

直接插入排序:

折半插入排序:

冒泡排序:

简单选择排序:

快速排序:

堆排序:

归并排序:

退出排序:

2、收获和体会:

在进行为期一个星期的课程设计中,最终完成了算法。

这期间,遇到的各种麻烦也都相继解决。

从这次实践中,我意识到自己还有很多不足之处。

首先先说一下基本的。

对于各种排序算法的过程还是不够熟悉,进行编程时还需要翻书查找,对于这一点,只能说对数据结构的学习还不够扎实,还需要在以后的学习中多多注意C++语言的学习和数据结构的相关知识。

其次,就是对于错误的处理,不能得心应手,不能正确处理一些简单的错误。

对于逻辑上的错误,不能够立即找到出错点,往往需要向同学请教才能找出错误,并且改正。

从总体上说,整个代码的实现还是存在不足的,例如本程序不能判断字符数大于1的字符串,没有相应排序的性能分析(如空间复杂度,时间复杂度),等等。

从这点看,说明自己的程序还是不够完善,不能做到十全十美,希望以后能有所修正。

总而言之,从这次的实践中我学到了很多东西,在以后的学习生活中要多多注意整顿自己的学风,严谨踏实的面对学习之中的问题。

3、源程序代码:

#include"stdafx.h"

#include

usingnamespacestd;

constintmaxsize=100;

intnum=0;//定义全局变量,为每一趟的输出做准备

intx=0;

template

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > IT计算机 > 互联网

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1