数据结构----各种排序算法的比较

一.实验目的

   实现常用的排序算法,加深对这些算法的理解,以后可以将这些算法应用到实际问题的解决上。


 二.实验题目

排序是在实际问题中经常用到的算法,快速、选择和插入三种排序算法是排序算法中最简单的也是最常用到的,实现这三种算法,在不同的数值序列上运行,然后比较三种方法的空间复杂度和时间复杂度,分析比较结果,得出选择这三种排序算法的一般原则。


三.实现提示

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


转载请注明出处.......




  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值