zoukankan      html  css  js  c++  java
  • 10种排序算法分析

    10种排序算法,分别是直接插入排序,折半插入排序,希尔排序,冒泡排序,快速排序,直接选择排序,树形排序,堆排序,归并排序,基数排序。各有千秋,但依旧有优劣之分,熟悉每一个算法,对于我们的代码优化,也将事半功倍。

    1,直接插入排序:

    基本思想:

    假设待排的n个记录存放在变量R中,首先将R[1]看做是有序区,将后n - 1个数组元素看作是无序区;然后将无序区的第一个元素R[2]插入到前面有序区的适当位置,从而得到新的有序区R[1..2];依次类推,经过n - 1趟直接插入排序后,得到有序区R[1..n] 。

    如果想要让数组以0开始,可以加一个temp 存储需要比较的值

    复制代码
    复制代码
     1 //1直接插入法
     2 template<class T>
     3 int InsertSort(T* pa,int n)
     4 {
     5     T temp;
     6     int count=0;
     7     for(int i = 1;i < n;i++)
     8     {
     9         temp = pa[i];
    10         int j = i;
    11         while(j >= 1 && temp<pa[j-1])
    12         {
    13             pa[j]=pa[j-1];
    14             j--;
    15             count++;                //移动次数
    16         }
    17         pa[j]=temp;
    18     }
    19     return count;
    20 }
    复制代码
    复制代码

    2,折半插入排序:

    基本思想:

    与直接插入排序类似,对于每一个待排的数据元素,在有序子集中实施折半查找,分左右两个分区,以减少比较次数。

    复制代码
    复制代码
     1 template<class T>
     2 int BinaryInsertSort(T* pa,int n)
     3 {
     4     T temp;
     5     int count=0;
     6     for(int i=1;i<n;i++)
     7     {
     8         temp=pa[i];
     9         int left=0,right=i-1;
    10         while(left<=right)
    11         {
    12             int middle = (left+right)/2;
    13             if(temp < pa[middle])
    14                 right = middle-1;
    15             else
    16                 left = middle+1;
    17         }
    18         for(int k=i-1;k>=left;k--)
    19         {
    20             pa[k+1]=pa[k];
    21             count++;                //移动次数
    22         }
    23         pa[left]=temp;
    24     }
    25     return count;
    26 }
    复制代码
    复制代码

    3,希尔排序

    基本算法思想:

    1)选定一个记录下标的增量gap,将整个记录序列按增量gap从第一个记录开始划分为若干组,对每组使用直接插入排序的方法;

    2)减小增量gap,不断重复上述过程,如此下去,直到gap=1(此时整个序列是一组)。

    复制代码
    复制代码
     1 //3.希尔排序
     2 template<class T>
     3 int ShellSort(T *pa,int n)
     4 {
     5     T temp;
     6     int count=0;
     7     int gap=n/2;
     8     while(gap)
     9     {
    10         for(int start=gap; start<2*gap && start<n; start++)
    11         {
    12             for(int i=start;i<n;i+=gap)
    13             {
    14                 temp=pa[i];
    15                 int j=i;
    16                 while(j>=gap && temp<pa[j-gap])
    17                 {
    18                     pa[j]=pa[j-gap];
    19                     j-=gap;
    20                     count++;
    21                 }
    22                 pa[j]=temp;
    23             }
    24             gap=gap/2;              //每组元素个数
    25         }
    26     }
    27     return count;
    28 }
    复制代码
    复制代码

    4,冒泡排序

    基本做法:

    1)(上冒)把各记录看作按纵向排列,然后自下而上地比较相邻记录的关键字kj和kj-1,若kj-1 > kj称为逆序,则两者交换位置;再将kj-1和kj-2进行比较,如有逆序则交换,直到全部关键字均比较一遍。这样一趟加工就使一个关键字上升到依其大小应该到达的位置。设有n个关键字,则经过n-1趟加工后,就使关键字从小到大、自上而下排列好了。

    2)(下沉)把各记录看作按纵向排列,然后自上而下地比较相邻记录的关键字kj和kj+1,若kj > kj+1称为逆序,则两者交换位置;再将kj+1和kj+2进行比较,如有逆序则交换,直到全部关键字均比较一遍。这样一趟加工就使一个关键字下沉到依其大小应该到达的位置。设有n个关键字,则经过n-1趟加工后,就使关键字从小到大、自上而下排列好了。

    复制代码
    复制代码
     1 //4.冒泡排序法
     2 template<class T>
     3 int BubbleSort(T *pa,int n)
     4 {
     5     T temp;
     6     int i=0,count=0;
     7     while(i<n-1)
     8     {
     9         int last=n-1;
    10         for(int j=n-1;j>i;j--)
    11         {
    12             if(pa[j]<pa[j-1])
    13             {
    14                 temp=pa[j-1];
    15                 pa[j-1]=pa[j];
    16                 pa[j]=temp;
    17                 last=j;
    18                 count++;
    19             }
    20         }
    21         i=last;
    22     }
    23     return count;
    24 }
    复制代码
    复制代码

    5,快速排序

    基本思想:

    在待排序文件中任取其中一个记录,通常选取第一个记录;以该记录的关键字为分界点,经过一趟排序后,将全部记录分成两个部分,所有关键字比分界点小的记录都放在它之前,所有关键字比分界点大的记录都放在它之后;然后再分别对这两个部分重复上述过程,直到每一部分只剩有一个记录为止。

    复制代码
    复制代码
     1 //5.快速排序
     2 template<class T>
     3 int Partition(T *pa,int low,int high)
     4 {
     5     int i=low,j=high;
     6     T temp=pa[i];
     7     while(i!=j)
     8     {
     9         while(pa[j]>=temp && j>i)
    10             j--;
    11         if(j>i)
    12         {
    13             pa[i++]=pa[j];
    14             n1++;
    15         }
    16         while(pa[i]<=temp && i<j)
    17             i++;
    18         if(i<j)
    19         {
    20             pa[j--]=pa[i];
    21             n1++;
    22         }
    23     }
    24     pa[i]=temp;
    25     return i;
    26 }
    27 
    28 template<class T>
    29 void QuickSort(T* pa,int low,int high)
    30 {
    31     if(low >= high)
    32         return;
    33     int m = Partition(pa,low,high);
    34     QuickSort(pa,low,m-1);
    35     QuickSort(pa,m+1,high);
    36 }
    37 
    38 template<class T>
    39 void QuickSort(T* pa,int n)
    40 {
    41     QuickSort(pa,0,n-1);
    42 }
    复制代码
    复制代码

    6,直接选择排序

    基本做法思想:

    直接通过比较关键字,首先在所有记录中选出关键字最小的记录,将它与第一个位置上的记录交换;然后在其余记录中选出关键字次小的记录,将它与第二个位置上的记录交换;依此类推,直至所有记录排成递增序列为止。

    复制代码
    复制代码
     1 //6.选择排序法
     2 template<class T>
     3 int SelectSort(T* pa,int n)
     4 {
     5     T temp;
     6     int count=0;
     7     for(int i=0;i<n-1;i++)
     8     {
     9         int min=i;
    10         for(int j=i+1;j<n;j++)
    11         {
    12             if(pa[j]<pa[min])
    13                 min=j;
    14         }
    15         if(min != i)
    16         {
    17             temp=pa[i];
    18             pa[i]=pa[min];
    19             pa[min]=temp;
    20             count++;
    21         }
    22     }
    23     return count;
    24 }
    复制代码
    复制代码

    7,二叉排序树排序:

    基本做法思想:

    首先对n个关键字(n个叶子结点)进行两两比较,然后将其中        个较小者之间再进行两两比较,如此重复,直至选出最小关键字为止;欲选出次小关键字,需将叶子结点中的最小关键字改为无穷大,并修改从该叶子结点到根的路径上各结点的值,则根结点的值即为次小关键字;重复以上操作,可依次选出从小到大的所有关键字。

    复制代码
    复制代码
      1 //8. 二叉排序树
      2 int PowerOfTwo(int n)
      3 {
      4     int k=2;
      5     while(k<n)
      6     {
      7         k=2*k;
      8     }
      9     return k;
     10 }
     11 template<class T>
     12 struct DataNode
     13 {
     14     T data;
     15     int index;
     16     int flag;
     17 };
     18 template<class T>
     19 bool operator<(const DataNode<T>&x,const DataNode<T>&y)
     20 {
     21     return(x.data<y.data);
     22 }
     23 template<class T>
     24 int Tournament(T* pa,int n)
     25 {
     26     DataNode<T> item;
     27     int count=0,s;
     28     int bottomsize=PowerOfTwo(n);
     29     int treesize=2*bottomsize-1;
     30     DataNode<T>* tree=new DataNode<T>[treesize];
     31     for(int j=bottomsize-1,i=0;j<treesize;j++,i++)
     32     {
     33         item.index=j;
     34         if(i<n)
     35         {
     36             item.data=pa[i];
     37             item.flag=1;
     38         }
     39         else
     40         {
     41             item.data=T();
     42             item.flag=0;
     43         }
     44         tree[j]=item;
     45     }
     46     i=bottomsize-1;
     47     while(i>0)
     48     {
     49         j=1;
     50         while(j<2*i)
     51         {
     52             if(tree[j+1].flag==0 || tree[j].data<tree[j+1].data)
     53             {
     54                 tree[(j-1)/2]=tree[j];
     55                 count++;
     56             }
     57             else
     58             {
     59                 tree[(j-1)/2]=tree[j+1];
     60                 count++;
     61             }
     62             j=j+2;
     63         }
     64         i=(i-1)/2;
     65     }
     66     for(i=0;i<n-1;i++)
     67     {
     68         pa[i]=tree[0].data;
     69         tree[tree[0].index].flag=0;
     70         s=UpdateTree(tree,tree[0].index);
     71         count=count+s;
     72     }
     73     pa[n-1]=tree[0].data;
     74     delete []tree;
     75     return count;
     76 }
     77 template<class T>
     78 int UpdateTree(DataNode<T>* tree,int i)
     79 {
     80     int count=0;
     81     tree[(i-1)/2]=( i%2 ==0 ? tree[i-1]:tree[i+1]);
     82     i=(i-1)/2;
     83     while(i>0)
     84     {
     85         int j=(i%2==0?i-1:i+1);
     86         if(tree[i].flag==0)
     87         {
     88             tree[(i-1)/2]=tree[j];
     89             count++;
     90         }
     91         else if(tree[j].flag==0)
     92         {
     93             tree[(i-1)/2]=tree[j];
     94             count++;
     95         }
     96         else if(tree[i]<tree[j])
     97         {
     98             tree[(i-1)/2]=tree[i];
     99             count++;
    100         }
    101         else
    102         {
    103             tree[(i-1)/2]=tree[j];
    104             count++;
    105         }
    106         i=(i-1)/2;
    107     }
    108     return count;
    109 }
    复制代码
    复制代码

    8,堆排序

    基本做法思想:

    对一组待排序记录的关键字,首先将它们按堆的定义排成一个序列,常称为建堆,从而输出堆顶的最大(或最小)关键字。然后对剩余的关键字再建堆,常称为重新调整成堆,即可得到次大(或次小)关键字,如此反复进行,直到全部关键字排成有序序列为止。

    复制代码
    复制代码
     1 //7.堆排序
     2 template<class T>
     3 void BuildHeap(T* pa,int size)
     4 {
     5     for(int i=size/2-1;i>=0;i--)
     6     {
     7         PercolateDown(pa,i,size);
     8     }
     9 }
    10 
    11 template<class T>
    12 void PercolateDown(T* pa,int pos,int size)
    13 {
    14     int p=pos,c=2*p+1;
    15     T temp=pa[p];
    16     while(c<size)
    17     {
    18         if(c+1<size && pa[c+1]>pa[c])
    19         {
    20             ++c;
    21         }
    22         if(temp >= pa[c])
    23             break;
    24         else
    25         {
    26             pa[p]=pa[c];
    27             p=c;
    28             c=2*p+1;
    29         }
    30     }
    31     pa[p]=temp;
    32 }
    33 
    34 template<class T>
    35 int HeapSort(T* pa,int n)
    36 {
    37     T temp;
    38     int count=0;
    39     BuildHeap(pa,n);
    40     for(int i=n-1;i>0;i--)
    41     {
    42         temp=pa[0];
    43         pa[0]=pa[i];
    44         pa[i]=temp;
    45         count++;
    46         PercolateDown(pa,0,i);
    47     }
    48     return count;
    49 }
    复制代码
    复制代码

    9,归并排序

    基本做法思想:

    对于一个长度为n的无序文件来说,归并排序把它看成是由n个只包括1个记录的有序文件组成的文件,然后进行两两归并,最后形成包含n个记录的有序文件。

    复制代码
    复制代码
     1 //9.归并排序
     2 template<class T>
     3 int Merge(T* ini,T* merge,int s,int m,int e)
     4 {
     5     int i=s,j=m+1,k=s;
     6     int count=0;
     7     while(i<=m &&j<=e)
     8     {
     9         if(ini[i]<ini[j])
    10         {
    11             merge[k++]=ini[i++];
    12             count++;
    13         }
    14         else
    15         {
    16             merge[k++]=ini[j++];
    17             count++;
    18         }
    19     }
    20     if(i<=m)
    21     {
    22         while(i<=m)
    23         {
    24             merge[k++]=ini[i++];
    25             count++;
    26         }
    27     }
    28     else
    29     {
    30         while(j<=e)
    31         {
    32             merge[k++]=ini[j++];
    33             count++;
    34         }
    35     }
    36     return count;
    37 }
    复制代码
    复制代码

    10,基数排序:

    基本做法思想:

    设立r个队列,队列编号分别为0 ~ r-1,(r为基数)

    (1)先按最低有效位的值,把n个关键字分配到这r个队列中,然后从小到大将各队列中的关键字再依次收集起来。

    (2)再按次低有效位的值把刚收集起来的关键字分配到r个队列中,重复收集工作。

    (3)重复地进行上述分配和收集,直到最高有效位。也就是说,如果数位为d,则需要重复进行d次。d由所有元素中最长的一个元素的位数计量。

    复制代码
    复制代码
     1 //10.基数排序
     2 int RadixSort(int* pa,int n)
     3 {
     4     Queue<int> Q[10];
     5     int base=1,flag=1,k,i;
     6     int count=0;
     7     while(flag)
     8     {
     9         for(i=0;i<n;i++)
    10         {
    11             k=(pa[i]/base)%10;
    12             Q[k].Push(pa[i]);
    13             count++;
    14         }
    15         base*=10;
    16         flag=0;
    17         i=0;
    18         for(k=0;k<10;k++)
    19         {
    20             while(!Q[k].Empty())
    21             {
    22                 pa[i++]=Q[k].Pop();
    23                 if(pa[i-1]/base!=0 && flag==0)
    24                 {
    25                     flag=1;
    26                 }
    27                 count++;
    28             }
    29         }
    30     }
    31     return count;
    32 }
    复制代码
    复制代码

    之前对这十种算法进行过具体分析,当时还计算了它的时间,引入#include<ctime>,加入clock()函数。

    这里是我的对于10种排序算法的比较代码,并且还运行成功,在这个代码里面,由于需要比较时间,所以数量必须要多。一个程序运行成功,几乎是纳秒级别的,所以,要扩大时间,并且使结果具有代表性,就要多加数据。

    复制代码
    复制代码
      1 #include<iostream>
      2 #include<ctime>
      3 #include"stdlib.h"
      4 #include"windows.h"
      5 #include"queue.h"
      6 #include"list.h"
      7 #define P 1234
      8 #define M 10
      9 using namespace std;
     10 static int n1=0;
     11 //1直接插入法
     12 template<class T>
     13 int InsertSort(T* pa,int n)
     14 {
     15     T temp;
     16     int count=0;
     17     for(int i = 1;i < n;i++)
     18     {
     19         temp = pa[i];
     20         int j = i;
     21         while(j >= 1 && temp<pa[j-1])
     22         {
     23             pa[j]=pa[j-1];
     24             j--;
     25             count++;                //移动次数
     26         }
     27         pa[j]=temp;
     28     }
     29     return count;
     30 }
     31 //2.折半插入法
     32 template<class T>
     33 int BinaryInsertSort(T* pa,int n)
     34 {
     35     T temp;
     36     int count=0;
     37     for(int i=1;i<n;i++)
     38     {
     39         temp=pa[i];
     40         int left=0,right=i-1;
     41         while(left<=right)
     42         {
     43             int middle = (left+right)/2;
     44             if(temp < pa[middle])
     45                 right = middle-1;
     46             else
     47                 left = middle+1;
     48         }
     49         for(int k=i-1;k>=left;k--)
     50         {
     51             pa[k+1]=pa[k];
     52             count++;                //移动次数
     53         }
     54         pa[left]=temp;
     55     }
     56     return count;
     57 }
     58 //3.希尔排序
     59 template<class T>
     60 int ShellSort(T *pa,int n)
     61 {
     62     T temp;
     63     int count=0;
     64     int gap=n/2;
     65     while(gap)
     66     {
     67         for(int start=gap; start<2*gap && start<n; start++)
     68         {
     69             for(int i=start;i<n;i+=gap)
     70             {
     71                 temp=pa[i];
     72                 int j=i;
     73                 while(j>=gap && temp<pa[j-gap])
     74                 {
     75                     pa[j]=pa[j-gap];
     76                     j-=gap;
     77                     count++;
     78                 }
     79                 pa[j]=temp;
     80             }
     81             gap=gap/2;              //每组元素个数
     82         }
     83     }
     84     return count;
     85 }
     86 
     87 //4.冒泡排序法
     88 template<class T>
     89 int BubbleSort(T *pa,int n)
     90 {
     91     T temp;
     92     int i=0,count=0;
     93     while(i<n-1)
     94     {
     95         int last=n-1;
     96         for(int j=n-1;j>i;j--)
     97         {
     98             if(pa[j]<pa[j-1])
     99             {
    100                 temp=pa[j-1];
    101                 pa[j-1]=pa[j];
    102                 pa[j]=temp;
    103                 last=j;
    104                 count++;
    105             }
    106         }
    107         i=last;
    108     }
    109     return count;
    110 }
    111 
    112 //5.快速排序
    113 template<class T>
    114 int Partition(T *pa,int low,int high)
    115 {
    116     int i=low,j=high;
    117     T temp=pa[i];
    118     while(i!=j)
    119     {
    120         while(pa[j]>=temp && j>i)
    121             j--;
    122         if(j>i)
    123         {
    124             pa[i++]=pa[j];
    125             n1++;
    126         }
    127         while(pa[i]<=temp && i<j)
    128             i++;
    129         if(i<j)
    130         {
    131             pa[j--]=pa[i];
    132             n1++;
    133         }
    134     }
    135     pa[i]=temp;
    136     return i;
    137 }
    138 
    139 template<class T>
    140 void QuickSort(T* pa,int low,int high)
    141 {
    142     if(low >= high)
    143         return;
    144     int m = Partition(pa,low,high);
    145     QuickSort(pa,low,m-1);
    146     QuickSort(pa,m+1,high);
    147 }
    148 
    149 template<class T>
    150 void QuickSort(T* pa,int n)
    151 {
    152     QuickSort(pa,0,n-1);
    153 }
    154 
    155 //6.选择排序法
    156 template<class T>
    157 int SelectSort(T* pa,int n)
    158 {
    159     T temp;
    160     int count=0;
    161     for(int i=0;i<n-1;i++)
    162     {
    163         int min=i;
    164         for(int j=i+1;j<n;j++)
    165         {
    166             if(pa[j]<pa[min])
    167                 min=j;
    168         }
    169         if(min != i)
    170         {
    171             temp=pa[i];
    172             pa[i]=pa[min];
    173             pa[min]=temp;
    174             count++;
    175         }
    176     }
    177     return count;
    178 }
    179 
    180 //7.堆排序
    181 template<class T>
    182 void BuildHeap(T* pa,int size)
    183 {
    184     for(int i=size/2-1;i>=0;i--)
    185     {
    186         PercolateDown(pa,i,size);
    187     }
    188 }
    189 
    190 template<class T>
    191 void PercolateDown(T* pa,int pos,int size)
    192 {
    193     int p=pos,c=2*p+1;
    194     T temp=pa[p];
    195     while(c<size)
    196     {
    197         if(c+1<size && pa[c+1]>pa[c])
    198         {
    199             ++c;
    200         }
    201         if(temp >= pa[c])
    202             break;
    203         else
    204         {
    205             pa[p]=pa[c];
    206             p=c;
    207             c=2*p+1;
    208         }
    209     }
    210     pa[p]=temp;
    211 }
    212 
    213 template<class T>
    214 int HeapSort(T* pa,int n)
    215 {
    216     T temp;
    217     int count=0;
    218     BuildHeap(pa,n);
    219     for(int i=n-1;i>0;i--)
    220     {
    221         temp=pa[0];
    222         pa[0]=pa[i];
    223         pa[i]=temp;
    224         count++;
    225         PercolateDown(pa,0,i);
    226     }
    227     return count;
    228 }
    229 //8. 二叉排序树
    230 int PowerOfTwo(int n)
    231 {
    232     int k=2;
    233     while(k<n)
    234     {
    235         k=2*k;
    236     }
    237     return k;
    238 }
    239 template<class T>
    240 struct DataNode
    241 {
    242     T data;
    243     int index;
    244     int flag;
    245 };
    246 template<class T>
    247 bool operator<(const DataNode<T>&x,const DataNode<T>&y)
    248 {
    249     return(x.data<y.data);
    250 }
    251 template<class T>
    252 int Tournament(T* pa,int n)
    253 {
    254     DataNode<T> item;
    255     int count=0,s;
    256     int bottomsize=PowerOfTwo(n);
    257     int treesize=2*bottomsize-1;
    258     DataNode<T>* tree=new DataNode<T>[treesize];
    259     for(int j=bottomsize-1,i=0;j<treesize;j++,i++)
    260     {
    261         item.index=j;
    262         if(i<n)
    263         {
    264             item.data=pa[i];
    265             item.flag=1;
    266         }
    267         else
    268         {
    269             item.data=T();
    270             item.flag=0;
    271         }
    272         tree[j]=item;
    273     }
    274     i=bottomsize-1;
    275     while(i>0)
    276     {
    277         j=1;
    278         while(j<2*i)
    279         {
    280             if(tree[j+1].flag==0 || tree[j].data<tree[j+1].data)
    281             {
    282                 tree[(j-1)/2]=tree[j];
    283                 count++;
    284             }
    285             else
    286             {
    287                 tree[(j-1)/2]=tree[j+1];
    288                 count++;
    289             }
    290             j=j+2;
    291         }
    292         i=(i-1)/2;
    293     }
    294     for(i=0;i<n-1;i++)
    295     {
    296         pa[i]=tree[0].data;
    297         tree[tree[0].index].flag=0;
    298         s=UpdateTree(tree,tree[0].index);
    299         count=count+s;
    300     }
    301     pa[n-1]=tree[0].data;
    302     delete []tree;
    303     return count;
    304 }
    305 template<class T>
    306 int UpdateTree(DataNode<T>* tree,int i)
    307 {
    308     int count=0;
    309     tree[(i-1)/2]=( i%2 ==0 ? tree[i-1]:tree[i+1]);
    310     i=(i-1)/2;
    311     while(i>0)
    312     {
    313         int j=(i%2==0?i-1:i+1);
    314         if(tree[i].flag==0)
    315         {
    316             tree[(i-1)/2]=tree[j];
    317             count++;
    318         }
    319         else if(tree[j].flag==0)
    320         {
    321             tree[(i-1)/2]=tree[j];
    322             count++;
    323         }
    324         else if(tree[i]<tree[j])
    325         {
    326             tree[(i-1)/2]=tree[i];
    327             count++;
    328         }
    329         else
    330         {
    331             tree[(i-1)/2]=tree[j];
    332             count++;
    333         }
    334         i=(i-1)/2;
    335     }
    336     return count;
    337 }
    338 //9.归并排序
    339 template<class T>
    340 int Merge(T* ini,T* merge,int s,int m,int e)
    341 {
    342     int i=s,j=m+1,k=s;
    343     int count=0;
    344     while(i<=m &&j<=e)
    345     {
    346         if(ini[i]<ini[j])
    347         {
    348             merge[k++]=ini[i++];
    349             count++;
    350         }
    351         else
    352         {
    353             merge[k++]=ini[j++];
    354             count++;
    355         }
    356     }
    357     if(i<=m)
    358     {
    359         while(i<=m)
    360         {
    361             merge[k++]=ini[i++];
    362             count++;
    363         }
    364     }
    365     else
    366     {
    367         while(j<=e)
    368         {
    369             merge[k++]=ini[j++];
    370             count++;
    371         }
    372     }
    373     return count;
    374 }
    375 //10.基数排序
    376 int RadixSort(int* pa,int n)
    377 {
    378     Queue<int> Q[10];
    379     int base=1,flag=1,k,i;
    380     int count=0;
    381     while(flag)
    382     {
    383         for(i=0;i<n;i++)
    384         {
    385             k=(pa[i]/base)%10;
    386             Q[k].Push(pa[i]);
    387             count++;
    388         }
    389         base*=10;
    390         flag=0;
    391         i=0;
    392         for(k=0;k<10;k++)
    393         {
    394             while(!Q[k].Empty())
    395             {
    396                 pa[i++]=Q[k].Pop();
    397                 if(pa[i-1]/base!=0 && flag==0)
    398                 {
    399                     flag=1;
    400                 }
    401                 count++;
    402             }
    403         }
    404     }
    405     return count;
    406 }
    407 int main()
    408 {
    409     int a[M][P],b[M][P],i,j;
    410               long count[10]={0},s=0;
    411     double begin[10],end[10];        //时间的开始和结束
    412     double t[10];
    413     srand(time(NULL));
    414     cout<<" "<<endl;
    415     for(i = 0; i <M;i++ )
    416     {
    417         for(j=0;j<P;j++)
    418         {
    419             a[i][j]=rand()%2000;      //获得的数据的范围在0~2000
    420          }
    421     }
    422 
    423 //------------------------------------------------直接插入法所得时间
    424     for(i = 0;i < M ;i++)
    425     {
    426         for(j = 0; j < P ;j++)
    427         {
    428             b[i][j]=a[i][j];
    429         }
    430     }
    431               begin[0]=clock();
    432     for(i=0;i<M;i++)
    433     {
    434         s=InsertSort(b[i],P);
    435         count[0]=count[0]+s;
    436               }
    437     end[0]=clock();
    438     t[0]=(double)(end[0]-begin[0])/CLOCKS_PER_SEC;
    439               cout<<"直接插入排序法的时间"<<t[0]<<'s'<<endl;
    440     cout<<" 直接插入的移动次数 "<<count[0]<<endl<<endl;
    441     
    442 //----------------------------------------------------折半插入法所得时间
    443     for(i = 0; i <M;i++ )
    444     {
    445         for(j=0;j<P;j++)
    446             b[i][j]=a[i][j];
    447     }
    448     s=0;
    449     begin[1]=clock();
    450     for(i=0;i<M;i++)
    451     {
    452         s=BinaryInsertSort(b[i],P);
    453         count[1]=count[1]+s;
    454     }
    455     end[1]=clock();    
    456     t[1]=(double)(end[1]-begin[1])/CLOCKS_PER_SEC;
    457     cout<<"折半插入所用时间:"<<t[1]<<'s'<<endl;
    458     cout<<"  折半 插入移动次数:"<<count[1]<<endl<<endl;
    459 //---------------------------------------------------希尔排序法所得时间
    460     for(i = 0; i <M;i++ )
    461     {
    462         for(j=0;j<P;j++)
    463             b[i][j] = a[i][j];
    464     }
    465     begin[2]=clock();
    466     for(i=0;i<M;i++)
    467     {
    468         s=ShellSort(b[i],P);
    469         count[2]=count[2]+s;
    470     }
    471     end[2]=clock();
    472     t[2]=(double)(end[2]-begin[2])/CLOCKS_PER_SEC;
    473     cout<<" 希尔排序法所用时间: "<<t[2]<<'s'<<endl;
    474     cout<<" 希尔排序的移动次数: "<<count[2]<<endl<<endl;    
    475 //-----------------------------------------------------冒泡排序法所得时间
    476     for(i = 0; i <M;i++ )
    477     {
    478         for(j=0;j<P ;j++)
    479             b[i][j] = a[i][j];
    480     }
    481     begin[3]=clock();
    482     for(i = 0;i < M;i++)
    483     {
    484         s=BubbleSort(b[i],P );
    485         count[3]=count[3]+s;
    486     }
    487     end[3]=clock();
    488     t[3]=(double)(end[3]-begin[3])/CLOCKS_PER_SEC;
    489     cout<<"冒泡排序法所用时间: "<<t[3]<<'s'<<endl;
    490     cout<<"  冒泡排序法移动次数:"<<count[3]<<endl<<endl;
    491 //--------------------------------------------------快速排序法所得时间
    492     for(i = 0; i <M;i++ )
    493     {
    494         for(j=0;j<P;j++)
    495             b[i][j]=a[i][j];
    496     }
    497     s=0;
    498     begin[4]=clock();
    499     for(i = 0;i < M; i++)
    500     {
    501         QuickSort(b[i],P);
    502     }
    503     count[4] = n1;
    504     end [4] = clock();
    505     t[4] = (double)(end[4]-begin[4]) / CLOCKS_PER_SEC;
    506     cout<<" 快速排序法所用时间: "<<t[4]<<'s'<<endl;
    507     cout<<"  快速排序法移动次数: "<<count[4]<<endl<<endl; 
    508 //-------------------------------------------------选择排序法所得时间    for(i = 0; i < M;i++ )
    509     {
    510         for(j = 0 ;j <P;j++)
    511             b[i][j]=a[i][j];
    512     }
    513     begin[5]=clock();
    514     for(i=0;i<M;i++)
    515     {
    516         s=SelectSort(b[i],P);
    517         count[5]=count[5]+s;
    518     }
    519     end[5]=clock();
    520     t[5]=(double)(end[5]-begin[5])/CLOCKS_PER_SEC;
    521     cout<<" 选择排序法所用时间:"<<t[5]<<'s'<<endl;
    522     cout<<" 选择排序法移动次数:"<<count[5]<<endl<<endl; 
    523 //----------------------------------------------------堆排序所得时间
    524     for(i = 0; i <M;i++ )
    525     {
    526         for(j = 0 ;j < P;j++)
    527             b[i][j] = a[i][j];
    528     }
    529 
    530     begin[6]=clock();
    531     for(i=0;i<M;i++)
    532     {
    533         s=HeapSort(b[i],P);
    534         count[6]=count[6]+s;
    535     }
    536     end[6]=clock();
    537     t[6]=(double)(end[6]-begin[6])/CLOCKS_PER_SEC;
    538     
    539     cout<<"堆排序所用时间:"<<t[6]<<'s'<<endl;
    540     cout<<"  堆排序移动次数:"<<count[6]<<endl<<endl;
    541     
    542 //-----------------------------------------------------二叉排序法所得时间
    543     for(i = 0; i <M;i++ )
    544     {
    545         for(j=0;j<P;j++)
    546             b[i][j]=a[i][j];
    547     }
    548     begin[7]=clock();
    549     for(i=0;i<5;i++)
    550     {
    551         s=Tournament(b[i],10000);
    552         count[7]=count[7]+s;
    553     }
    554     end[7]=clock();
    555     t[7]=(double)(end[7]-begin[7])/CLOCKS_PER_SEC;
    556     cout<<"二叉排序法所用时间为:"<<t[7]<<'s'<<endl;
    557     cout<<" 二叉排序法 的移动次数为:"<<count[7]<<endl<<endl;   
    558 //-----------------------------------------------------------归并排序法所得时间
    559     for(i = 0; i <M;i++ )
    560     {
    561         for(j=0;j<P;j++)
    562             b[i][j]=a[i][j];
    563     }
    564     int a1[M][P];
    565     for(i = 0; i <M;i++ )
    566     {
    567         for(j=0;j<P;j++)
    568                a1[i][j]=a[i][j];
    569                }
    570     begin[8]=clock();
    571     for(i=0;i<5;i++)
    572     {
    573         s=Merge(a[i],a1[i],0,5000,P);
    574         count[8]=count[8]+s;
    575     } 
    576     Sleep(1000);
    577     end[8]=clock();
    578     t[8]=(double)(end[8]-begin[8]-1000)/CLOCKS_PER_SEC;
    579     cout<<"归并排序所用时间为:"<<t[8]<<'s'<<endl;
    580     cout<<" 归并排序的移动次数: "<<count[8]<<endl<<endl;    
    581 //------------------------------------------------------基数排序法所得时间
    582     for(i = 0; i <M;i++ )
    583     {
    584         for(j=0;j<P;j++)
    585             b[i][j]=a[i][j];
    586     }
    587     begin[9]=clock();
    588     for(i=0;i<M;i++)
    589     {
    590         s=RadixSort(b[i],P);
    591         count[9]=count[9]+s;
    592     }
    593     end[9]=clock();
    594     t[9]=(double)(end[9]-begin[9])/CLOCKS_PER_SEC; 
    595     cout<<"基数排序所用时间为:"<<t[9]<<'s'<<endl;
    596     cout<<" 基数排序移动次数为: "<<count[9]<<endl<<endl;    
    597 //--------------------------------------------------------
    598 
    599     return 0;
    600 }

    复制代码
    复制代码

    为了方便大家参考分析,同时也给出代码中所提到的list.h文件和queue.h文件。

    list.h文件:

    复制代码
    复制代码
      1 #ifndef LIST_H
      2 #define LIST_H
      3 
      4 #include<stdlib.h>
      5 
      6 template<class T>
      7 class List
      8 {
      9     struct Node                //双向结点声明
     10     {
     11         T data;    
     12         Node *prev,*next;
     13         Node(const T &d=T(),Node *p=NULL,Node *n=NULL):data(d),prev(p),next(n){}
     14     };
     15     int size;                //数据结点个数
     16     Node *head;                //头结点指针
     17     Node *tail;                //尾结点指针
     18     void init()                //初始化函数
     19     {size=0;head=new Node;tail=new Node;head->next=tail;tail->prev=head;}
     20 
     21 public:
     22     class const_iterator
     23     {
     24     protected:
     25         Node *current;
     26         T& retrieve()const{return current->data;}
     27         const_iterator(Node *p):current(p){}
     28         friend class List<T>;
     29     public:
     30         const_iterator():current(NULL){}
     31         const T& operator*()const{return retrieve();}//current->data
     32         const_iterator& operator++()//前++
     33         {
     34             current=current->next;
     35             return *this;
     36         }
     37         const_iterator operator++(int)//后++
     38         {
     39             const_iterator old=*this;    //old=current;
     40             ++(*this);                    //current=current->next;
     41             return old;
     42         }
     43         const_iterator& operator--()//前--
     44         {
     45             current=current->prev;
     46             return *this;
     47         }
     48         const_iterator operator--(int)//后--
     49         {
     50             const_iterator old=*this;    //old=current;
     51             --(*this);                    //current=current->next;
     52             return old;
     53         }
     54         bool operator==(const const_iterator & rhs)const
     55             {return current==rhs.current;}
     56         bool operator!=(const const_iterator & rhs)const
     57             {return current!=rhs.current;}
     58 
     59     };
     60     class iterator:public const_iterator
     61     {
     62     protected:
     63         iterator(Node *p):const_iterator(p){}
     64         friend class List<T>;
     65     public:
     66         iterator(){}
     67         T& operator*(){return retrieve();}
     68         const T& operator*()const{return const_iterator::operator*();}
     69         iterator& operator++()//前++
     70         {
     71             current=current->next;
     72             return *this;
     73         }
     74         iterator operator++(int)//后++
     75         {
     76             iterator old=*this;            //old=current;
     77             ++(*this);                    //current=current->next;
     78             return old;
     79         }
     80         iterator& operator--()//前--
     81         {
     82             current=current->prev;
     83             return *this;
     84         }
     85         iterator operator--(int)//后--
     86         {
     87             iterator old=*this;            //old=current;
     88             --(*this);                    //current=current->next;
     89             return old;
     90         }
     91     };
     92     List(){init();}                                //默认构造函数
     93     List(const List<T> &l){init();operator=(l);}//复制构造函数
     94     ~List(){Clear();delete head;delete tail;}    //析构函数
     95     const List& operator=(const List& l);        //复制赋值运算符函数
     96     int Size()const{return size;}                //求数据个数
     97     bool Empty()const{return size==0;}            //判空函数
     98     void  Clear(){while(!Empty())Pop_front();}    //清表
     99 
    100     iterator begin(){return iterator(head->next);}
    101     const_iterator begin()const{return const_iterator(head->next);}
    102     iterator end(){return iterator(tail);}
    103     const_iterator end()const{return const_iterator(tail);}
    104     
    105     T& Front(){return *begin();}            //返回首元素的引用
    106     const T& Front()const{return *begin();}    //返回首元素的常量型引用
    107     T& Back(){return *--end();}                //返回尾元素的引用            
    108     const T& Back()const{return *--end();}    //返回尾元素的常量型引用
    109     void Push_front(const T& item){Insert(begin(),item);}//首插
    110     void Push_back(const T& item){Insert(end(),item);}//尾插
    111     void Pop_front(){Erase(begin());}        //删除首结点
    112     void Pop_back(){Erase(--end());}        //删除尾结点
    113     iterator Erase(iterator itr);            //删除指示器位置上的结点
    114     iterator Insert(iterator itr,const T& item);//在指示器的位置插入item
    115 
    116 };
    117 template<class T>//复制赋值成员运算符函数的实现
    118 const List<T>& List<T>::operator=(const List<T>& l)
    119 {
    120     Clear();                    //清为空表
    121     for(const_iterator itr=l.begin();itr!=l.end();++itr) //把表l的结点逐个复制
    122         Push_back(*itr);
    123     return *this;
    124 }
    125 
    126 template<class T>
    127 List<T>::iterator List<T>::Erase(iterator itr)
    128 {
    129     Node *p=itr.current;
    130     iterator re(p->next);
    131     p->prev->next=p->next;
    132     p->next->prev=p->prev;
    133     delete p;
    134     size--;
    135     return re;
    136 }
    137 template<class T>
    138 List<T>::iterator List<T>::Insert(iterator itr,const T& item)
    139 {
    140     Node *p=itr.current;
    141     size++;
    142     p->prev->next=new Node(item,p->prev,p);
    143     p->prev=p->prev->next;
    144     return iterator(p->prev);
    145 }
    146 
    147 #endif
    复制代码
    复制代码

    queue.h文件:

    复制代码
    复制代码
     1 #ifndef QUEUE_H
     2 #define    QUEUE_H
     3 
     4 #include"list.h"
     5 template<class T>
     6 class Queue
     7 { 
     8     List<T> queueL;
     9 public:
    10     Queue(){}
    11     ~Queue(){}
    12     int Size()const                //求长
    13         {return queueL.Size();}    
    14     bool Empty()const            //判空
    15         {return queueL.Empty();}    
    16     const T& Front()const            //取队头项
    17         {return queueL.Front();}    
    18      void Push(const T& item)        //入队
    19         {queueL.Push_back(item);}
    20     T Pop()                    //出队
    21         { T item=queueL.Front(); queueL.Pop_front(); return item;}
    22     void Clear()                //置空队
    23         {queueL.Clear();}    
    24 };
    25 
    26 
    27 #endif
    复制代码
    复制代码

    运行结果:

    综上结果可见,快速排序,堆排序,归并排序的效率较高。

    转载

  • 相关阅读:
    双管齐下采用压缩传输加快网页显示速度
    努力奋斗第一天
    cefSharp在XP下使得程序崩溃记录
    SVN记住用户名和密码后如何修改
    如果把编程语言比作武器
    cefSharp 设置运行时系统语言
    C# 检测机器是否有声卡设备
    C# 中判断程序是否启动使用Mutex使用异常
    chm 字体修改
    最近两年的生活
  • 原文地址:https://www.cnblogs.com/HUANGRONG888/p/6263001.html
Copyright © 2011-2022 走看看