王吉玉《算法与数据结构》课程设计—排序算法性能分析
目录
摘要 (1)
前言 (2)
正文 (3)
1.采用类C语言定义相关的数据类型 (3)
2.各模块的伪码算法 (3)
3.函数的调用关系图 (7)
4.调试分析 (7)
5.测试结果 (8)
6.源程序(带注释) (11)
总结 (20)
参考文献 (21)
致谢 (22)
附件Ⅰ部分源程序代码 (23)
摘要
计算机的日益发展,其应用早已不局限于简单的数值运算,而涉及到问题的分析、数据结构框架的设计以及插入、删除、排序、查找等复杂的非数值处理和操作。算法与数据结构的学习就是为以后利用计算机资源高效地开发非数值处理的计算机程序打下坚实的理论、方法和技术基础。
算法与数据结构旨在分析研究计算机加工的数据对象的特性,以便选择适当的数据结构和存储结构,从而使建立在其上的解决问题的算法达到最优。
数据结构是在整个计算机科学与技术领域上广泛被使用的术语。它用来反映一个数据的内部构成,即一个数据由哪些成分数据构成,以什么方式构成,呈什么结构。数据结构有逻辑上的数据结构和物理上的数据结构之分。逻辑上的数据结构反映成分数据之间的逻辑关系,而物理上的数据结构反映成分数据在计算机内部的存储安排。数据结构是数据存在的形式。
《算法与数据结构》主要介绍一些最常用的数据结构及基本算法设计,阐明各种数据结构内在的逻辑关系,讨论其在计算机中的存储表示,以及在其上进行各种运算时的实现算法,并对算法的效率进行简单的分析和讨论。数据结构是介于数学、计算机软件和计算机硬件之间的一门计算机专业的核心课程。它是计算机程序设计、数据库、操作系统、编译原理及人工智能等的重要基础,广泛的应用于信息学、系统工程等各种领域。
学习数据结构是为了将实际问题中所涉及的对象在计算机中表示出来并对它们进行处理。通过课程设计可以提高学生的思维能力,促进学生的综合应用能力和计算机编程技能,找出自己的不足,在以后的学习中更加努力!
本次的课程设计主要是对《算法与数据结构》的所有内部排序算法进行了一个汇总、集合,并通过算法设计实现对其性能的分析和评价。在设计过程中重温了C语言中的基本语法以及个别函数的用法,巩固了设计思维方向。
关键词:排序算法;性能分析;排序算法性能分析;C语言
前言
排序是计算机程序设计中的一种重要操作。它的功能是将一个数据元素的任意序列,重新排列成一个按关键字有序的序列。内部排序的方法很多,但是就其全面性能而言,很难提出一种被认为是最好的方法,每一种方法都有各自的优缺点,适合在不同的环境下使用。如果按排序过程中依据的不同原则对内部排序方法进行分类,则大致可分为插入排序,冒泡排序,快速排序,归并排序、选择排序、堆排序等。
本课程实现了对应用于随机、正序、逆序等数据录入方式,针对各内部排序的算法,并分析算法的复杂程度,记录排序过程中的比较次数和移动次数;另通过动画形象表现出了各排序算法的排序过程,使人一目了然。
正文
1.采用类c语言定义相关的数据类型
#define N 1000//定义数组最大为100
const int t=3;//定义希尔排序次数
int d[3]={4,3,1};//定义希尔排序比较量
int m;
int qmt;//快速排序的移动次数
int qct;//快速排序的比较次数printf("%d\t",)
2.各模块的伪码算法
(1) 直接插入排序
InsertSort(Recordnode R[], int n)
{
for(i=2;<=n;++i)
if(R[i] { R[0]=R[i]; for(j=i-1;R[0] R[j+1]=R[j];//记录后移 R[j+1]=R[0];//插入到正确位置 } } (2)折半插入排序 BinsertSort(Recordnode R[],int n) { for(i=2;<=n;++i) { low=1;high=i-1; while(low<=high) { m=(low+hige)/2 if(R[0] for(j=i-1;j>=high+1;--j) R[j+1]=R[j]; R[high+1]=R[0]; } } (3)希尔排序 ShellSort(Recordnode R[], int n) { //用希尔排序法对一个记录r[]排序 int i,j,d; int bool; int x; d=n; do{ d=[d/2]; bool=1 for(i=1;i<=L.length-d;i++) { j=i+d if(R[i]>R[j]) { x=R[i]; R[i]=R[j]; bool=0 } } while(d>1) } } (4) 冒泡排序 void BubbleSort(SeqList R) { //R(1…n)是待排序的文件,采用自上向下扫描,对R做冒泡排序int i,j; Boolean exchange; //交换标志 for(i=1;i { //最多做n-1趟排序 exchange=FALSE; //本趟排序开始前,交换标志应为假 for(j=n-1;j<=i;j--) //对当前无序区R[i…n]自下向上扫描 if(R[j+1].key { R[0]=R[j+1]; //R[0]不是哨兵,仅做暂存单元 R[j+1]=R[j]; R[j]=R[0]; exchange=TRUE; //发生了交换,故将交换标志置为真 } if(!exchange) //本趟排序未发生交换,提前终止算法return; } } (5) 快速排序 void QuickSort(SeqList R,int low,int high) { //对R[low…high]快速排序 int pivotpos; //划分后的基准记录的位置 if(low { //仅当区间长度大于1时才须排序 pivotpos=Partition(R,low,high); //对R[low…high]做划分 QuickSort(R,low,pivotpos-1); //对做区间递归排序 QuickSort(R,pivotpos+1,high); //对右区间递归排序 } }//QuickSort int Partition(SeqList R,int i,int j) { //调用Partition(R,low.high)时,对R[low…high]做划分,返回基准记录的位置ReceType pivot=R[i]; //用区间的第1个记录作为基准 while(i {//从区间两端交替向中间扫描,直至i=j为止 while(i j--; //从右向左扫描,查找第1个关键字小于pivot.key的记录R[j] if(i R[i++]=R[j]; //相当于交换R[i]和R[j],交换后i指针加1 while(i i++; //从左向右扫描,查找第1个关键字大于pivot.key的记录R[i] if(i R[j--]=R[i]; //相当于交换R[i]和R[j],交换后j指针减1 } R[i]=pivot; //基准记录已被最后定位 return i; } //partition 3. 函数的调用关系图 4. 调试分析 a 、调试中遇到的问题及对问题的解决方法 (1) 对随机函数的应用中怎样保证其每次产生随机序列的不重复 解决办法:利用系统时间,调用time 函数 (2) 排序中移动次数和比较次数的确定 解决办法:动态跟踪函数循环,并分析 b、算法的时间复杂度和空间复杂度 5.测试结果 6.源程序(带注释) #include #include #include #include #define N 1000//定义数组最大为100 const int t=3;//定义希尔排序次数 int d[3]={4,3,1};//定义希尔排序比较量 int m; int qmt;//快速排序的移动次数 int qct;//快速排序的比较次数 void randoming(int a[]) { srand((int)time(0)); for(int x=0;x<1000;x++) printf("%d\t",rand()%100); } void output(int n,int a[],int ct,int mt)//内部排序中调用的输出函数{ int i; printf("\n排序结果:"); for( i=0;i printf("%d\t",a[i]);//输出各排序完成的数组printf("\n比较次数:%d\n",ct);//输出各排序比较次数 printf("移动次数:%d\n\n",mt);//输出各排序移动次数 } void bubble_sort(int n,int A[])//冒泡排序 { int mt=0;//移动次数mt=movetime int ct=0;//比较次数ct=cmdtime int i,j,temp; int a[N]; for(i=0;i a[i]=A[i];//使数组a[]与数组A[]完全相同,对数组a[]进行操作(不改动A[],可以使A[]被其他函数调用) for(i=0;i { for(j=0;j { if(a[j+1] temp=a[j], a[j]=a[j+1], a[j+1]=temp, mt+=3;//关键字交换计为3次移动 } } printf("冒泡排序"); output(n,a,ct,mt); } void selection_sort(int n,int A[])//选择排序 { int mt=0;//移动次数movetime int ct=0;//比较次数cmdtime int i,j,temp,k; int a[N]; for(i=0;i a[i]=A[i];//使数组a[]与数组A[]完全相同,对数组a[]进行操作 (不改动A[],可以使A[]被其他函数调用) for(i=0;i { k=i; for(j=i+1;j if(a[k]>a[j]) k=j; temp=a[i], a[i]=a[k], a[k]=temp, mt+=3;//关键字交换计为3次移动} printf("选择排序"); output(n,a,ct,mt); } void quick(int a[],int low,int up)//快速排序递归算法 { int i,j,temp; if(low { i=low; j=up; temp=a[low], qmt++; while(i!=j) { qct++; while(i j--, qct++; if(i a[i++]=a[j], qct++; qmt++; while(i i++, qct++; if(i a[j--]=a[i], qct++, qmt++; } a[i]=temp, qmt++; quick(a,low,j-1); quick(a,i+1,up); } } void quick_sort(int n,int A[])//快速排序(通过调用快速排序递归算法完成) { int i; int a[N]; for(i=0;i a[i]=A[i];//使数组a[]与数组A[]完全相同,对数组a[]进行操作(不改动A[],可以使A[]被其他函数调用) quick(a,0,n-1);//调用快速排序递归算法 printf("快速排序"); output(n,a,qct,qmt); } void insertion_sort(int n,int A[])//插入排序 { int mt=0;//移动次数movetime int ct=0;//比较次数cmdtime int i,j,temp; int a[N]; for(i=0;i a[i]=A[i];//使数组a[]与数组A[]完全相同,对数组a[]进行操作(不改动A[],可以使A[]被其他函数调用) for(i=1;i { temp=a[i], mt++; for(j=i-1;j>=0&&temp a[j+1]=a[j], mt++; a[j+1]=temp, mt++; } printf("插入排序"); output(n,a,ct,mt); } void shell_sort(int n,int A[])//希尔排序 { int mt=0;//移动次数movetime int ct=0;//比较次数cmdtime int i,j,k,h,y; int a[N];