数据结构----各种排序算法的比较
来源:互联网 发布:淘宝拍图片用什么相机 编辑:程序博客网 时间:2024/05/17 02:24
一.实验目的
实现常用的排序算法,加深对这些算法的理解,以后可以将这些算法应用到实际问题的解决上。
二.实验题目
排序是在实际问题中经常用到的算法,快速、选择和插入三种排序算法是排序算法中最简单的也是最常用到的,实现这三种算法,在不同的数值序列上运行,然后比较三种方法的空间复杂度和时间复杂度,分析比较结果,得出选择这三种排序算法的一般原则。
三.实现提示
1.待排序列的数据结构描述:
#define MAXSIZE 20 //一个用作示例的顺序表的最大长度 typedef int KeyType; //定义关键字类型为整数类型 typedef struct { KeyType key; //关键字项 InfoType otherifo; //其他数据项 }RedType; //记录类型 typedef struct { RedType r[MAXSIZE+1]; //r[0]闲置或用作哨兵单元 int length; //顺序表的长度 }SqList; //顺序表类型
2.待排序列应该考虑多种情况,例如基本有序以及基本无序的情况等,这样才能得到在不同的数据情况下算法优劣性的比较。
四.思考及选做
1.进一步探讨其他的排序算法的比较,得出类似的时间复杂度以及空间复杂度的分析,特别要注意针对不同的算法,测试数据的结构也要尽可能的丰富。
五.我的实现
(1) 排序算法的实现
#include<stdio.h> #include<stdlib.h> #define MAXSIZE 20 //一个用作示例的顺序表的最大长度 /*************************************数据结构的定义*************************************/ typedef int KeyType; //定义关键字类型为整数类型 typedef char InfoType; typedef struct { KeyType key; //关键字项 InfoType otherifo; //其他数据项 }RedType; //记录类型 typedef struct { RedType r[MAXSIZE+1]; //r[0]闲置或用作哨兵单元 int length; //顺序表的长度 }SqList; //顺序表类型 /****************************************功能函数*****************************************/ /* 快速排序. 思想:选定一个枢纽元素,对待排序序列进行分割, 分割之后的序列一个部分小于枢纽元素,一个部分大于枢纽元素,再 对这两个分割好的子序列进行上述的过程。 总结:平均效率O(nlogn),适用于排序大列表。 此算法的总时间取决于枢纽值的位置;选择第一个元素作为枢纽,可能 导致O(n2)的最糟用例效率。若数基本有序,效率反而最差。选项中间 值作为枢纽,效率是O(nlogn)。基于分治法。 */ void QuickSort(SqList &L,int l,int h) { if (l>=h) return ; int j ,i,key; i=l; j=h; key=L.r[i].key; while(i<j) { while(i<j&&L.r[j].key>key) j--; if (i<j) L.r[i++].key=L.r[j].key; while (i<j&&L.r[i].key<key) i++; if (i<j) L.r[j--].key=L.r[i].key; } L.r[i].key=key; if (l<i-1) QuickSort(L,l,i-1); if (i+1<h) QuickSort(L,i+1,h); } /* 选择排序。 思想:每一趟从待排序的数据元素中选出最小(或最大)的一个元素,顺序 放在已排好序的数列的最后,直到全部待排序的数据元素排完。 选择排序是不稳定的排序方法。 */ void SelectSort(SqList &L) { int i,j,m,n=L.length+1 ; int t ;//临时变量 for(i=1;i<n;i++) { m=i ; for(j=i+1;j<n;j++) { if(L.r[j].key<L.r[m].key) m=j; } if(m!=i) { t=L.r[i].key; L.r[i].key=L.r[m].key; L.r[m].key=t ; } } } /* 插入排序。 思想:将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据。 最佳效率O(n);最糟效率O(n2)与冒泡、选择相同,适用于排序小列表 若列表基本有序,则插入排序比冒泡、选择更有效率。 */ void InsertSort(SqList &L) { // 对顺序表L作直接插入排序。 int i,j; for (i=2; i<=L.length; ++i) if (L.r[i].key<L.r[i-1].key) { // "<"时,需将L.r[i]插入有序子表 L.r[0] = L.r[i]; // 复制为哨兵 for (j=i-1; L.r[0].key<L.r[j].key; --j) L.r[j+1] = L.r[j]; // 记录后移 L.r[j+1] = L.r[0]; // 插入到正确位置 } } /* 打印函数. 打印当前表. */ void myPrint(SqList &L) { for(int i = 1;i<MAXSIZE+1;i++) { printf("%d ",L.r[i].key); } printf("\n"); } /***************************************main函数*************************************/ int main() { //1. 输入20随机数 SqList s,s1,s2,s3; s.length=20; for(int i = 1;i<MAXSIZE+1;i++) { scanf("%d",&(s.r[i].key)); } s1=s2=s3=s; //2. 对随机数分别进行排序 printf("快速排序--->未排序前的序列:\n"); myPrint(s); QuickSort(s3,1,s3.length); //快速排序 printf("排序后的序列:\n"); myPrint(s3); printf("选择排序--->未排序前的序列:\n"); myPrint(s); SelectSort(s1); //选择排序 printf("排序后的序列:\n"); myPrint(s1); printf("插入排序--->未排序前的序列:\n"); myPrint(s); InsertSort(s2); //插入排序 printf("排序后的序列:\n"); myPrint(s2); system("PAUSE"); return 0; }
(2) 算法性能比较
#include<stdio.h> #include<stdlib.h> #include <time.h> //使用当前时钟做种子 #define MAXSIZE 10000 //一个用作示例的顺序表的最大长度 /*************************************数据结构的定义*************************************/ typedef int KeyType; //定义关键字类型为整数类型 typedef char InfoType; typedef struct { KeyType key; //关键字项 InfoType otherifo; //其他数据项 }RedType; //记录类型 typedef struct { RedType r[MAXSIZE+1]; //r[0]闲置或用作哨兵单元 int length; //顺序表的长度 }SqList; //顺序表类型 /****************************************功能函数*****************************************/ /* 快速排序. 思想:选定一个枢纽元素,对待排序序列进行分割, 分割之后的序列一个部分小于枢纽元素,一个部分大于枢纽元素,再 对这两个分割好的子序列进行上述的过程。 总结:平均效率O(nlogn),适用于排序大列表。 此算法的总时间取决于枢纽值的位置;选择第一个元素作为枢纽,可能 导致O(n2)的最糟用例效率。若数基本有序,效率反而最差。选项中间 值作为枢纽,效率是O(nlogn)。基于分治法。 */ void QuickSort(SqList &L,int l,int h) { if (l>=h) return ; int j ,i,key; i=l; j=h; key=L.r[i].key; while(i<j) { while(i<j&&L.r[j].key>key) j--; if (i<j) L.r[i++].key=L.r[j].key; while (i<j&&L.r[i].key<key) i++; if (i<j) L.r[j--].key=L.r[i].key; } L.r[i].key=key; if (l<i-1) QuickSort(L,l,i-1); if (i+1<h) QuickSort(L,i+1,h); } /* 选择排序。 思想:每一趟从待排序的数据元素中选出最小(或最大)的一个元素,顺序 放在已排好序的数列的最后,直到全部待排序的数据元素排完。 选择排序是不稳定的排序方法。 */ void SelectSort(SqList &L) { int i,j,m,n=L.length+1 ; int t ;//临时变量 for(i=1;i<n;i++) { m=i ; for(j=i+1;j<n;j++) { if(L.r[j].key<L.r[m].key) m=j; } if(m!=i) { t=L.r[i].key; L.r[i].key=L.r[m].key; L.r[m].key=t ; } } } /* 插入排序。 思想:将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据。 最佳效率O(n);最糟效率O(n2)与冒泡、选择相同,适用于排序小列表 若列表基本有序,则插入排序比冒泡、选择更有效率。 */ void InsertSort(SqList &L) { // 对顺序表L作直接插入排序。 int i,j; for (i=2; i<=L.length; ++i) if (L.r[i].key<L.r[i-1].key) { // "<"时,需将L.r[i]插入有序子表 L.r[0] = L.r[i]; // 复制为哨兵 for (j=i-1; L.r[0].key<L.r[j].key; --j) L.r[j+1] = L.r[j]; // 记录后移 L.r[j+1] = L.r[0]; // 插入到正确位置 } } /* 产生10000个随即数。 产生1万个随机。数并进行排序。统计他所消耗的时间。 */ SqList random() { SqList s; s.length=10000; int i,j; srand((int)time(0)); for(i=0;i<10000;i++) { j=1+(int)(1000.0*rand()/(RAND_MAX+1.0)); s.r[i].key=j; } return s; } /***************************************计算时间的main函数*************************************/ int main() { SqList s1; s1.length=10000; clock_t start,end; //快速排序 s1 = random(); start = clock(); QuickSort(s1,1,s1.length); end = clock(); printf( "对1万个数进行快速排序的时间为%lf秒\n ", (double)(end-start)/CLOCKS_PER_SEC); //选择排序 s1 = random(); start = clock(); SelectSort(s1); end = clock(); printf("对1万个数进行选择排序的时间为%lf秒\n ", (double)(end-start)/CLOCKS_PER_SEC); //插入排序 s1 = random(); start = clock(); InsertSort(s1); end = clock(); printf("对1万个数进行插入排序的时间为%lf秒\n ", (double)(end-start)/CLOCKS_PER_SEC); system("PAUSE"); return 0; }
转载请注明出处.......
- 数据结构----各种排序算法的比较
- 数据结构的各种排序算法稳定性比较
- 数据结构----各种排序算法的比较
- [数据结构]各种排序算法比较
- 数据结构中各种内部排序算法的比较
- 数据结构中各种内部排序算法的比较
- 数据结构中各种内部排序算法的比较
- 数据结构中各种内部排序算法的比较
- 数据结构中各种内部排序算法的比较
- 数据结构中各种排序算法比较
- 数据结构中各种排序算法比较
- 数据结构中各种排序算法比较
- 各种排序算法的比较
- 各种排序算法的比较
- 各种排序算法的比较
- 各种排序算法的比较
- 各种排序算法的比较
- 各种排序算法的比较
- read 不会设置缓冲区最后一个字节为 '\0'
- 2012年上半年的系统分析师考试小结
- Android之apk文件签名——keytool 和 jarsigner
- Android开发环境的搭建
- 中国历史[图]
- 数据结构----各种排序算法的比较
- c++类对象和指针的区别
- HDOJ 2473 Junk-Mail Filter(并查集 要用到代理的思想)
- 有关接口的那些事
- CWnd中PreCreateWindow、PreSubclassWindow、SubclassWindow的区别
- RedHat Enterprise Linux 5 安装TFTP服务器和NFS服务器
- 命令查询网址
- Spring MVC
- 接口 抽象类