10种排序算法分析

Posted W+7

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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
复制代码
复制代码

运行结果:

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

-转载

以上是关于10种排序算法分析的主要内容,如果未能解决你的问题,请参考以下文章

基于比较的七种常见排序算法

基于比较的七种常见排序算法

基于比较的七种常见排序算法

几种排序算法分析

几种排序算法分析

几种排序算法分析