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

来源:互联网 发布:淘宝拍图片用什么相机 编辑:程序博客网 时间: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; }  


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




原创粉丝点击