安徽工业大学数据结构课程设计.docx
- 文档编号:10259328
- 上传时间:2023-02-09
- 格式:DOCX
- 页数:51
- 大小:759.70KB
安徽工业大学数据结构课程设计.docx
《安徽工业大学数据结构课程设计.docx》由会员分享,可在线阅读,更多相关《安徽工业大学数据结构课程设计.docx(51页珍藏版)》请在冰豆网上搜索。
安徽工业大学数据结构课程设计
数据结构课程设计
网101
一.排序算法比较
1.问题描述
对直接插入排序,直接选择排序,冒泡排序,快速排序,堆排序五种排序算法进行比较.
要求:
1.被排序的对象由计算机随机生成,分别取长度为500,20000,1000000
2.算法中增加比较移动次数和比较次数的统计功能,并统计在排序同一组随机数时每种排序算法的运行时间,及占用内存情况.
3.对实验的结果进行比较
2.设计思路
这是一个算法性能评价程序,重点在于算法性能的评价上.实现某一功能可能有很多方法,
判断一个算法好坏的标准主要有时间复杂度和空间复杂度.在当今系统资源相对充足的计算机系统中,时间复杂度变成了头等问题.
对于每一个排序算法都应该有两个返回值:
比较次数和移动次数.但在C语言中只能有一个函数返回值,故这里采用指针传递地址的方式通过形参的地址从而可以修改实参值.这样一来,在每个排序算法参数列表中,除了含被排序指针对象外,另外加两个整型变量指针,用于传递算法执行过程中的比较次数和移动次数.
取一定长度的对象,由计算机产生一定量的伪随机数后,主函数,调用各个排序函数,但由于排序对象也是指向一维数组的指针,在调用一次排序算法后,通过形参对指针的改变,被排序对象已经是有序的了.当再一次用其他排序算法后,有可能比较次数和移动次数达到最大或最小.无论是哪种情况都是不好的,这样一来,就失去了算法复杂度的比较意义了.为了避免这种情况的出现本程序采用在排序前新建一个数组,将保存随机数的数组复制到该数组,让排序算法对该数组进行排序.这样就不会改变原始对象的随机性.
在统计排序算法运行时间时采用新建两个time_t对象,排序开始前接收一次系统时间,排序结束后接收一次系统时间,二者的差值即为排序算法所运行的时间。
3.数据结构设计
本程序中考虑的内容是排序对象,排序的依据是关键字之间的大小比较。
故在每个节点类型定义中,至少得包含关键字key这一项。
被排序对象由一个个节点构成,一个排序对象包含一系列指向一串节点的指针,指针对象长度。
具体说明如下:
typedefstruct
{
KeyTypekey;//关键字
intother;//数据
}DataType;//节点类型
typedefstruct
{
DataTyper[1000000];
intlength;//排序对象的大小
}Sqlist;//排序对象类型
4.功能函数设计
(1)直接插入排序函数StrightInsertSort()
直接插入排序将待排序对象分为有序部分和无序部分,进行排序时逐次顺序提取无序部分的对象同有序部分的最后一个对象做比较,如果该对象大于有序部分最后一个对象,则将该对象插入到此位置,否则依次向左比较,直至找到插入位置。
(2)直接选择排序函数Selectsort()
该排序算法首先在所有的n个带排序对象中找到最小的对象,将其与第1个对象做交换后,在后n-1个对象中继续找到最大对象,找到后将其与第2个对象交换。
直至将所有的对象找到并插入适当位置即可。
(3)冒泡排序函数BubbleSort()
在每一趟冒泡排序中,依次比较相邻两个关键字的大小。
若为反序,则交换。
经过一趟冒泡后最大的关键字已经到达最后了。
若按这种方法进行n-1趟冒泡,排序既能完成。
(4)堆排序函数Heapsort()
对排序的算法思想很简单,就是每次把关键字调整为堆,取出堆顶元素与最后一个元素交换,同时令堆的大小减一,把剩下的元素重新调整为堆,重复此过程,直到只剩下一个元素为止。
(5)快速排序函数
将带排序记录的第一个记录作为分区标准,将小于其的元素放在左边,将大于其的元素放在右边,中间放所选记录,为一趟快速排序。
然后对两个子序列如此排序,直至所有记录有序。
5.程序代码
#include"stdafx.h"
#include"stdio.h"
#include"stdlib.h"
#include"time.h"
#include"windows.h"
#include"psapi.h"
#include"iostream"
usingnamespacestd;
#pragmaonce
#pragmacomment(lib,"Psapi.lib")
typedefintKeyType;
typedefstruct
{
KeyTypekey;
intother;
}DataType;
typedefstruct
{
DataTyper[1000000];
intlength;
}Sqlist;
voidcopy(Sqlist*a,Sqlist*b);//复制
intGetMemory();//得到系统开销状况
voidSrandNum(Sqlist*s,intnum);//生成随机数
voidStrightInsertSort(Sqlist*s,long*compare,long*exchange);//直接插入排序
voidBubbleSort(Sqlist*s,long*compare,long*exchange);//冒泡排序
voidQuicksort(Sqlist*s,intlow,inthigh,long*compare,long*exchange);//递归形式的快速排序
voidSelectsort(Sqlist*s,long*compare,long*exchange);//直接选择排序
voidHeapsort(Sqlist*s,long*compare,long*exchange);//堆排序
voidout(Sqlist*s);//输出排序结果
int_tmain(intargc,_TCHAR*argv[])//主函数
{
inti,num;
long*compare,*exchange;//记录比较及交换次数
compare=(long*)malloc(sizeof(long));//开辟空间
exchange=(long*)malloc(sizeof(long));
Sqlist*s,*tmp;
s=(Sqlist*)malloc(sizeof(Sqlist));
tmp=(Sqlist*)malloc(sizeof(Sqlist));
printf("请输入生成的随机数的数目:
\n");
cin>>num;
SrandNum(s,num);//生成随机数
time_tstart,end;//start,end分别记录开始及结束时系统时间
//printf("\n生成的随机数如下:
\n");
//out(s);
printf("直接插入排序情况:
\n");//直接插入排序
copy(s,tmp);
*compare=*exchange=0;
start=clock();
StrightInsertSort(tmp,compare,exchange);
end=clock();
printf("排序运行时间%dms\n",end-start);
printf("比较次数:
%d交换次数:
%d",*compare,*exchange);
//printf("\n排序结果如下\n");
//out(tmp);
printf("\n\n冒泡排序情况:
\n");//冒泡排序
copy(s,tmp);
*compare=*exchange=0;
start=clock();
BubbleSort(tmp,compare,exchange);
end=clock();
printf("排序运行时间%dms\n",end-start);
printf("比较次数:
%d交换次数:
%d",*compare,*exchange);
//printf("\n排序结果如下\n");
//out(tmp);
printf("\n\n快速排序情况:
\n");//快速排序
copy(s,tmp);
*compare=*exchange=0;
start=clock();
Quicksort(tmp,1,tmp->length,compare,exchange);
end=clock();
printf("排序运行时间%dms\n",end-start);
printf("比较次数:
%d交换次数:
%d",*compare,*exchange);
//printf("\n排序结果如下\n");
//out(tmp);
printf("\n\n直接选择排序情况:
\n");//直接选择排序
copy(s,tmp);
*compare=*exchange=0;
start=clock();
Selectsort(tmp,compare,exchange);
end=clock();
printf("排序运行时间%dms\n",end-start);
printf("比较次数:
%d交换次数:
%d",*compare,*exchange);
//printf("\n排序结果如下\n");
//out(tmp);
printf("\n\n堆排序情况:
\n");//堆排序
copy(s,tmp);
*compare=*exchange=0;
start=clock();
Heapsort(tmp,compare,exchange);
end=clock();
printf("排序运行时间%dms\n",end-start);
printf("比较次数:
%d交换次数:
%d",*compare,*exchange);
//printf("\n排序结果如下\n");
//out(tmp);
return0;
}
voidcopy(Sqlist*a,Sqlist*b)//将a复制到b中
{
inti;
for(i=1;i
b->r[i].key=a->r[i].key;
b->length=a->length;
}
voidSrandNum(Sqlist*s,intnum)//生成num个随机数保存到s中
{
inti;
time_tt;
srand((unsigned)time(&t));//新建时间种子
for(i=1;i<=num;i++)
s->r[i].key=rand();//生成随机数
s->length=num;
}
voidStrightInsertSort(Sqlist*s,long*compare,long*exchange)//直接插入排序
{
inti,j;
*compare=*exchange=0;
for(i=2;i
{
s->r[0]=s->r[i];//复制到前哨站
(*compare)++;
(*exchange)++;
j=i-1;
while(s->r[0].key
{
(*compare)++;
(*exchange)++;
s->r[j+1]=s->r[j];
j--;
}
s->r[j+1]=s->r[0];//插入到正确的位置
(*exchange)++;
}
}
voidBubbleSort(Sqlist*s,long*compare,long*exchange)//冒泡排序
{
inti,j;
for(i=1;i<=s->length-1;i++)
for(j=2;j<=1+s->length-i;j++)//进行n-1趟冒泡
if(s->r[j].key
{
s->r[0].key=s->r[j].key;
s->r[j].key=s->r[j-1].key;
s->r[j-1].key=s->r[0].key;
(*exchange)+=3;
(*compare)++;
}
}
intQuicksort1(Sqlist*s,intlow,inthigh,long*compare,long*exchange)//一趟快速排序
{//交换顺序表s中的记录,使轴值到达其最终位置,并返回轴值的位置
//此时,在轴值之前的数字都小于它,在轴值后面的数字都大于它
intpivotkey;
s->r[0]=s->r[low];//以子表的第一个记录作为轴值支点
pivotkey=s->r[low].key;//取轴值的关键字
(*exchange)+=2;
while(low { (*compare)++; while(low { high--; (*compare)+=2; } s->r[low]=s->r[high];//将比轴值记录小的交换到低端 (*exchange)++; while(low { low++; (*compare)+=2; } s->r[high]=s->r[low];//将比轴值记录大的交换到高端 (*exchange)++; } s->r[low]=s->r[0];//轴值到达其最终位置 (*exchange)++; returnlow;//返回轴值最终所在位置 } voidQuicksort(Sqlist*s,intlow,inthigh,long*compare,long*exchange)//递归形式的快速排序 { intpivotloc; if(low { (*compare)++; pivotloc=Quicksort1(s,low,high,compare,exchange);//将待排序序列一分为二 Quicksort(s,low,pivotloc-1,compare,exchange);//将小于轴值的序列实现递归排序 Quicksort(s,pivotloc+1,high,compare,exchange);//将大于轴值的序列实现递归排序 } } voidSelectsort(Sqlist*s,long*compare,long*exchange)//直接选择排序 { inti,j,t; DataTypetmp; for(i=1;i { (*compare)++; for(j=i+1,t=i;j<=s->length;j++)//在i开始的length-i+1条记录中选取关键字最小的记录 { (*compare)++; if(s->r[t].key>s->r[j].key) { (*compare)++; t=j;//t中存放关键字最小的记录的下标 (*exchange)++; } } tmp=s->r[t];//将关键字最小的记录与第i条记录交换 s->r[t]=s->r[i]; s->r[i]=s->r[t]; (*exchange)+=3; } } voidHeapAdjust(Sqlist*s,intn,intm,long*compare,long*exchange)//对第n个结点为跟的子树筛选,使其成为大顶堆 { inti=n,j; DataTyperc; rc=s->r[n]; (*exchange)++; for(j=2*i;j<=m;j*=2)//沿着关键字较大的孩子向下搜索 { if(j { j=j+1;//j为较大孩子的坐标 (*compare)+=2; (*exchange)++; } if(rc.key>s->r[j].key) { break;//rc应插在i位置上 (*compare)++; } s->r[i]=s->r[j]; i=j;//使i结点满足堆定义 (*exchange)+=2; } s->r[i]=rc;//插入 (*exchange)++; } voidHeapsort(Sqlist*s,long*compare,long*exchange)//堆排序 { inti; DataTypetmp; for(i=s->length/2;i>0;i--)//将数据建成堆 { (*compare)++; HeapAdjust(s,i,s->length,compare,exchange); } for(i=s->length;i>1;i--) { tmp=s->r[1];//将堆顶元素与堆底元素交换,将最大元素一道最后 s->r[1]=s->r[i]; s->r[i]=tmp; (*compare)++; (*exchange)+=3; HeapAdjust(s,1,i-1,compare,exchange); } } voidout(Sqlist*s)//输出结果 { inti; for(i=1;i<=s->length;i++) printf("%d",s->r[i].key); } 6.运行测试 (1).排序正确性验证 将主函数做适当调整,在排序前输出待排序的数字,待排序完成后输出排序结果。 调整后的主函数如下: int_tmain(intargc,_TCHAR*argv[]) { inti,num; long*compare,*exchange;//记录比较及交换次数 compare=(long*)malloc(sizeof(long));//开辟空间 exchange=(long*)malloc(sizeof(long)); Sqlist*s,*tmp; s=(Sqlist*)malloc(sizeof(Sqlist)); tmp=(Sqlist*)malloc(sizeof(Sqlist)); printf("请输入生成的随机数的数目: \n"); cin>>num; SrandNum(s,num);//生成随机数 time_tstart,end;//start,end分别记录开始及结束时系统时间 printf("\n生成的随机数如下: \n"); out(s); printf("直接插入排序情况: \n");//直接插入排序 copy(s,tmp); printf("\n生成的随机数如下: \n"); out(tmp); *compare=*exchange=0; start=clock(); StrightInsertSort(tmp,compare,exchange); end=clock(); printf("\n排序后结果如下: \n"); out(tmp); printf("\n\n冒泡排序情况: \n");//冒泡排序 copy(s,tmp); printf("\n生成的随机数如下: \n"); out(tmp); *compare=*exchange=0; start=clock(); BubbleSort(tmp,compare,exchange); end=clock(); printf("\n排序后结果如下: \n"); out(tmp); printf("\n\n快速排序情况: \n");//快速排序 copy(s,tmp); printf("\n排序前如下: \n"); out(tmp); *compare=*exchange=0; start=clock(); Quicksort(tmp,1,tmp->length,compare,exchange); end=clock(); printf("\n排序后结果如下: \n"); out(tmp); printf("\n\n直接选择排序情况: \n");//直接选择排序 copy(s,tmp); printf("\n排序前如下: \n"); out(tmp); *compare=*exchange=0; start=clock(); Selectsort(tmp,compare,exchange); end=clock(); printf("\n排序后结果如下: \n"); out(tmp); printf("\n\n堆排序情况: \n");//堆排序 copy(s,tmp); printf("\n排序前如下: \n"); out(tmp); *compare=*exchange=0; start=clock(); Heapsort(tmp,compare,exchange); end=clock(); printf("\n排序后结果如下: \n"); out(tmp); return0; } 用随机生成函数分别生成5个,10个对排序算法的正确性进行验证,验证运行结果如下: 观察运行结果,证明每次排序前待排序对象复制正确,复制前后一致,排序结果正确。 (2)排序性能比较 用程序代码中的主函数,输入生成的随机数的数目,对排序算法进行比较: 这是一个长度为5678的五种排序算法比较次数和移动次数的统计可以看出,直接插入排序的比较次数和冒泡排序的比较次数基本相同,在8130000左右,直接选择排序的比较次数最多,大概为直接插入排序(冒泡排序的2倍),冒泡排序的交换次数也最多,快速排序和堆排序的比较次数和交换次数较少,算法明显优于其他排序算法。 而通过运行时间的分析可以得到快速排序和堆排序较快,直接选择排序和直接插入排序相差不大,冒泡排序最满。 观察结果除如上结论为还可以看出快速排序比堆排序更好。 (当对87654组对象进行排序时,快速排序运行时间(51ms)<堆排序运行时间(65ms),快速排序比较次数(39902723)>堆排序比较次数(1403682),快速排序交换次数(851286)<堆排序比较次数(3714052)). 由此可知,在
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 安徽 工业大学 数据结构 课程设计
![提示](https://static.bdocx.com/images/bang_tan.gif)