数据结构c语言设计比较各种排序方法的效率.docx
《数据结构c语言设计比较各种排序方法的效率.docx》由会员分享,可在线阅读,更多相关《数据结构c语言设计比较各种排序方法的效率.docx(26页珍藏版)》请在冰豆网上搜索。
数据结构c语言设计比较各种排序方法的效率
课程设计说明书
设计名称:
程序设计语言强化课程设计
题目:
比较各种排序方法的效率
*******************
专业:
网络工程
班级:
10网络工程2
学号:
**********
*********************
日期:
2012年3月8日
课程设计任务书
一、设计题目
比较各种排序方法的效率
二、主要内容
选择四种以上的排序方法,采用随机生成的数据,登记并比较各个排序方法的比较次数和交换次数,验证各个排序方法效率的理论分析的结果。
三、具体要求
围绕课程设计的目的和意义,基本要求如下:
每次随机生成的数据不小于100个
采用顺序存储结构,登记多次结果
经过大量的统计计算,给出各种排序方法的平均效率的比较。
把统计结果与理论分析结论进行对照。
四、进度安排
1、资料查找、系统分析,概要设计;时间安排2天
2、系统详细设计、功能设计;时间安排2天
3、算法实现、编程调试;时间安排5-7天
4、资料整理、课程设计说明书编写。
时间安排1天
五、完成后应上交的材料
1、课程设计说明书(所使用的数据结构说明、程序流程图、功能模块图、核心算法等)
2、相关源程序文件
六、总评成绩
指导教师签名日期年月日
系主任审核日期年月日
一、设计任务的主要算法分析……………………………………………1
1.1主要算法具体分析………………………………………………2
二、程序的流程图…………………………………………………………3
各种排序算法的N-S图……………………………………3
1.总流程图模块…………………………………………3
2.直接插入排序模块…………………………………………4
3.冒泡排序模块…………………………………………5
4.简单选择模块……………………………………………5
5.快速排序模块……………………………………6
6.堆排序模块………………………………………6
三、各个模块的源代码…………………………………………………7
3.1各种排序算法………………………………………………7
1.直接插入排序函数…………………………………………7
2.冒泡排序函数………………………………………………8
3.简单选择排序函数…………………………………………9
4.快速排序函数………………………………………………10
5.堆排序函数…………………………………………………11
6.输出函数……………………………………………………13
7.随机生成函数…………………………………………………13
8.主函数…………………………………………………16
四、程序运行效果图……………………………………………………20
4.1登陆画面………………………………………………20
4.2各种排序结果显示画面(100个数据随机生成5次)…21
4.3总的、平均的比较次数和交换次数显示画面(100个数据随机生成5次)………………………………………………………………23
4.4总的、平均的比较次数和交换次数显示画面(1000个数据随机生成100次)……………………………………………………24
五、使用说明……………………………………………………………24六、设计心得…………………………………………………………24
6.1课程设计中遇到的主要问题和解决方法…………………24
6.2本程序的创新和得意之处…………………………………25
6.3设计中存在的不足及改进的设想…………………………25
6.4本次课程设计的感想和心得体会…………………………25
一.算法分析
直接插入排序:
将记录插入到已排好序的有序表中,得到一个新的,记录数增加的有序表。
冒泡排序:
是基于交换排序的一种算法。
它是依次两两比较待排序元素;若为逆序(递增或递减)则进行交换,将待排序元素从左至右比较一遍称为一趟“冒泡”。
每趟冒泡都将待排序列中的最大(小)关键字交换到最后位置,直到全部元素有序为止。
简单选择排序:
令i从1至n-1,进行n-1趟选择操作。
快速排序:
通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记录继续进行排序,已达到整个序列有序。
堆排序:
使记录序列按关键字非递减有序排列,则在堆排序的算法中先建一个“大顶堆”,即先选得一个关键字为最大的记录并与序列中最后一个记录交换,然后对序列中前n-1记录进行筛选,重新将它调整为一个“大顶堆”,如此反复直至排序结束。
随机生成函数:
用srand((unsigned)time(NULL))随机生成数据并使用不同排序方法排序。
定义结构体数组
typedefintkeytype;//定义关键字类型为整型
typedefstruct{
keytypekey;
}datatype;//记录类型
datatypeR[MAXSIZE];//定义结构体数组
1.1主要算法具体分析:
这个排序算法设计个以静态结构体应用为基础加上C的基础语法一起的一个综合系统程序。
1主程序是goto语句和for循环的应用
2直接插入函数是一个将记录插入到已排好序的静态数组的应用
3冒泡排序函数是一个将数据不断交换排序的应用
4简单选择函数是一个从n-i+1个记录中选出最小关键字并和第i个记录交换的应用
5快速排序函数是一个将每趟记录分成独立两部分并比较交换的应用
6堆排序函数是一个将记录建成堆并交换的排序的应用
7随机生成函数是用srand((unsigned)time(NULL))随机生成数据的应用
8输出函数是一个对排好序的组数输出的应用
二.程序的流程图
2.1总流程图
说明:
利用判断语句判断,若n<100则执行goto语句;利用for循环语句执行随机生成函数并输出结果。
2.2直接插入排序函数
说明:
利用外循环for语句,内嵌判断语句if(R[i].key
2.3冒泡排序函数
说明:
利用内外循环for语句,并判断if(R[j].key>R[j+1].key)进行排序。
2.4简单选择函数
说明:
for外循环,内嵌for循环和判断语句来进行选择交换排序。
2.5快速排序函数
说明:
判断if(low2.6堆排序函数
说明:
执行第一个for循环,不断调用HeapAdjust(R,i,n)函数;执行第二个for循环,不断交换数据和HeapAdjust(R,1,i-1)函数。
三.原代码程序
3.1各种排序算法
#include
#include
#include
#include
#defineMAXSIZE50000
typedefintkeytype;//定义关键字类型为整型
typedefstruct{
keytypekey;
}datatype;//记录类型
datatypeR[MAXSIZE];//定义结构体数组
inta[5]={0},b[5]={0};//分别定义比较次数和交换次数
doublec[5],Ttime;
//<一>直接插入排序
voidInsert_Sort(datatypeR[],intn)//直接插入排序
{
inti,j;
for(i=2;i<=n;++i)
{
a[0]++;
if(R[i].keyR[0]=R[i];//复制为哨兵
R[i]=R[i-1];
b[0]+=2;
for(j=i-2;R[0].key{R[j+1]=R[j];//记录后移
b[0]++;
a[0]++;
}
if(j!
=0)a[0]++;
R[j+1]=R[0];//插入到正确位置
b[0]++;
}
}
}
//<二>冒泡排序
voidBubble_Sort(datatypeR[],intn)//冒泡排序
{
inti,j;
for(i=1;i<=n-1;i++)
for(j=1;j<=n-i;j++)
{
a[1]++;
if(R[j].key>R[j+1].key)
{
R[0]=R[j];
R[j]=R[j+1];//将R[j]与R[j+1]交换
R[j+1]=R[0];
b[1]+=3;
}
}
}
//<三>简单选择排序
voidSelect_Sort(datatypeR[],intn)//简单选择排序
{
inti,j,k;
for(i=1;i{
k=i;
for(j=i+1;j<=n;j++)
{
a[2]++;
if(R[j].keyk=j;}
if(i!
=k)
{
R[0]=R[k];
R[k]=R[i];//将R[k]与R[i]交换
R[i]=R[0];
b[2]+=3;
}
}
}
//<四>快速排序
intPartition(datatypeR[],intlow,inthigh)
{
intpivotkey;
R[0]=R[low];
b[3]++;
pivotkey=R[low].key;//枢轴记录关键字
while(low{
while(low=pivotkey)
{a[3]++;--high;}
if(low{R[low]=R[high];//将比枢轴记录小的记录移到低端
a[3]++;b[3]++;}
while(low{a[3]++;++low;}
if(low{R[high]=R[low];//将比枢轴记录大的记录移到高端
a[3]++;b[3]++;}
}
R[low]=R[0];b[3]++;
returnlow;//返回枢轴位置
}//Partition
voidQSort(datatypeR[],intlow,inthigh)//快速排序
{
inti;
if(low{
i=Partition(R,low,high);//将R[low..high]一分为二
QSort(R,low,i-1);//对低子表递归排序,i是枢轴位置
QSort(R,i+1,high);//对高子表递归排序
}
}//QSort
//<五>堆排序
voidHeapAdjust(datatypeR[],ints,intm)
{
datatyperc;intj;
rc=R[s];
for(j=2*s;j<=m;j*=2)//沿key较大的孩子节点向下筛选
{
if(j{a[4]++;++j;}//j为key较大记录的下标
if(ja[4]++;
if(rc.key>R[j].key)break;
R[s]=R[j];b[4]++;
s=j;
}
R[s]=rc;//插入
}//HeapAdjust
voidHeapSort(datatypeR[],intn)//堆排序
{
inti;
for(i=n/2;i>0;--i)
HeapAdjust(R,i,n);//将R[1..n]建成大顶堆
for(i=n;i>1;--i)
{
R[0]=R[1];
R[1]=R[i];//将R[1]与R[i]交换
R[i]=R[0];
b[4]+=3;
HeapAdjust(R,1,i-1);//将R[1..i-1]重新调整为大顶堆
}
}//HeapSort
//<六>输出函数
voidPri(datatypeR[],intn)//输出函数
{
inti;
for(i=1;i<=n;i++)
printf("%d",R[i].key);
printf("\n");
}
//<七>随机生成函数
voidrand_select(intn)//随机生成函数
{
inti;
LARGE_INTEGERm_liPerfFreq={0};LARGE_INTEGERm_liPerfStart={0};
LARGE_INTEGERliPerfNow={0};
datatypeR1[MAXSIZE],
R2[MAXSIZE],R3[MAXSIZE],R4[MAXSIZE];
for(i=1;i<=n;i++)
{
printf("%d",R[i].key=rand()%n);
}
printf("\n");
for(i=1;i<=n;i++)
R1[i].key=R[i].key;
for(i=1;i<=n;i++)
R2[i].key=R[i].key;
for(i=1;i<=n;i++)
R3[i].key=R[i].key;
for(i=1;i<=n;i++)
R4[i].key=R[i].key;
QueryPerformanceFrequency(&m_liPerfFreq);
QueryPerformanceCounter(&m_liPerfStart);//计时开始
Insert_Sort(R,n);//直接插入排序
QueryPerformanceCounter(&liPerfNow);//计时结束
Ttime=((liPerfNow.QuadPart)-(m_liPerfStart.QuadPart))
*1000.0/m_liPerfFreq.QuadPart;
c[0]+=Ttime;
printf("插入排序后数据的顺序:
\n");
Pri(R,n);
QueryPerformanceFrequency(&m_liPerfFreq);
QueryPerformanceCounter(&m_liPerfStart);//计时开始
Bubble_Sort(R1,n);//冒泡排序
QueryPerformanceCounter(&liPerfNow);//计时结束
Ttime=((liPerfNow.QuadPart)-(m_liPerfStart.QuadPart))
*1000.0/m_liPerfFreq.QuadPart;
c[1]+=Ttime;
printf("冒泡排序后数据的顺序:
\n");
Pri(R1,n);
QueryPerformanceFrequency(&m_liPerfFreq);
QueryPerformanceCounter(&m_liPerfStart);//计时开始
Select_Sort(R2,n);//简单选择排序
QueryPerformanceCounter(&liPerfNow);//计时结束
Ttime=((liPerfNow.QuadPart)-(m_liPerfStart.QuadPart))
*1000.0/m_liPerfFreq.QuadPart;
c[2]+=Ttime;
printf("简单排序数据的顺序:
\n");
Pri(R2,n);
QueryPerformanceFrequency(&m_liPerfFreq);
QueryPerformanceCounter(&m_liPerfStart);//计时开始
QSort(R3,1,n);//快速排序
QueryPerformanceCounter(&liPerfNow);//计时结束
Ttime=((liPerfNow.QuadPart)-(m_liPerfStart.QuadPart))
*1000.0/m_liPerfFreq.QuadPart;
c[3]+=Ttime;
printf("快速排序后数据的顺序:
\n");
Pri(R3,n);
QueryPerformanceFrequency(&m_liPerfFreq);
QueryPerformanceCounter(&m_liPerfStart);//计时开始
HeapSort(R4,n);//堆排序
QueryPerformanceCounter(&liPerfNow);//计时结束
Ttime=((liPerfNow.QuadPart)-(m_liPerfStart.QuadPart))
*1000.0/m_liPerfFreq.QuadPart;
c[4]+=Ttime;
printf("堆排序后数据的顺序:
\n");
Pri(R4,n);
}
//<八>主函数
voidmain()
{
inti,n,t;srand((unsigned)time(NULL));//使用系统定时/计数器的值
//做为随机种子每次运行,显示的随机数会是伪随机数,结果都不同
printf("\n");
printf("\n");
printf("\n");
printf("*------------------------*\n");
m:
printf("|请输入随机生成数据的个数|\n");
printf("*------------------------*\n");
scanf("%d",&n);
if(n<100)
{
printf("取数个数不能小于100,请重新输入\n");
gotom;
}
printf("\n");
printf("\n");
printf("*--------------------*\n");
printf("|请输入随机生成的次数|\n");
printf("*--------------------*\n");
scanf("%d",&t);
printf("\n");
for(i=0;i{
printf("电脑第%d次随机生成数据为:
\n",i+1);
rand_select(n);
printf("统计第%d次随机数据的比较次数和交换次数为\n",i+1);
printf("*------------------------------------------------------*\n");
printf("********排序方式比较次数交换次数耗时\n");
printf("\n");
printf("********直接%-10d\t%-10d\t%-12f\n",a[0],b[0],c[0]);
printf("\n");
printf("********冒泡%-10d\t%-10d\t%-12f\n",a[1],b[1],c[1]);
printf("\n");
printf("********简单选择%-10d\t%-10d\t%-12f\n",a[2],b[2],c[2]);
printf("\n");
printf("********快速排序%-10d\t%-10d\t%-12f\n",a[3],b[3],c[3]);
printf("\n");
printf("********堆排序%-10d\t%-10d\t%-12f\n",a[4],b[4],c[4]);
printf("*------------------------------------------------------*\n");
printf("\n");
}
printf("求得平均比较次数和平均移动次数为\n");
printf("*------------------------------------------------------*\n");
printf("********排序方式平均比较次数平均交换次数平均耗时\n");
printf("\n");
printf("********直接%-10d\t%-10d\t%-12f\n",a[0]/t,b[0]/t,c[0]/t);
printf("\n");
printf("********冒泡%-10d\t%-10d\t%-12f\n",a[1]/t,b[1]/t,c[1]/t);
printf("\n");
printf("********简单选择%-10d\t%-10d\t%-12f\n",a[2]/t,b[2]/t,c[2]/t);
printf("\n");
printf("********快速排序%-10d\t%-10d\t%-12f\n",a[3]/t,b[3]/t,c[3]/t);
printf("\n");
printf("********堆排序%-10d\t%-10d\t%-12f\n",a[4]/t,b[4]/t,c[4]/t);
printf("*-------------------------------------------------------*\n");
}
4程序运行效果
4.1登陆界面(100个数据随机生成5次)
4.2各种排序结果显示画面(100个数据随机生成5次)
第1次生成画面:
(100个数据随机生成5次)
第5次生成画面:
4.3总的和平均的比较次数和交换次数显示
(100个数据随机生成5次)
4.4总的和平均的比较次数和交换次数显示
(1000个数据随机生成100次)
五.使用说明
本设计比较各种排序算法的效率能在家用或公用计算机上的VC软件上使用.
六.设计心得
(1)课程设计中遇到的主要问题和解决方法:
上学期刚学完数据结构这本书,毕竟都很少实践操作,做这个比较排序算法的效率都有些挑战,在这个课程设计中,主要是对于一些基本的知识,熟悉程度不够,特别是对于比较次数和交换次数的统计,刚开始是跟理论值相差甚大,然后自己看了好几遍的书和上网看了一些例题,