找到最快的算法,一直是计算机界的目标之一,而排序就是其中最基本的算法。什么样的排序才是最快的呢?
1.最少的比较次数,算法理论证明n个数排序,如果是基于比较的算法,至少需要 ㏒(n!) 向上取整数。下面给出小数目下,最少比较次数:
n | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
㏒(n!) | 0 | 1 | 3 | 5 | 7 | 10 | 13 | 16 |
2.移动次数最少,根据群论置换群理论,n个数的序列,变换到这n个数组成另一个序列,一定可以在最多n次移动内做到。
在理论的指引下,人们开始寻找这些传说中的极限。人们开始简单地完成了n=1,2,3,4的极限算法,但是当n=5时,人们长期停留在了8次比较。但是在1956年,H.B.Demuth在终于首先找到5个次7次比较的排序方法,并在他的博士论文中进行了阐述。下面就是对这个算法的C语言实现:
- /* 1956年H.B.Demuth找到的5个数7次的比较方法,后来Lester Ford,Selmer Johnson归并插入排序中使用*/
- /********************************************************************
- * 示意图如下 *
- * *
- * [0] [1] 排序得 [0]<=[1] *
- * [2] [3] 排序得 [2]<=[3] *
- * [1] [3] 排序得 [1]<=[3] *
- * 此时有关系:[0]<=[3],,[2]<=[1]<=[3] *
- * *
- * [1] [4] *
- * _______|_______ *
- * | | *
- * [1]<=[4] [1]>[4] *
- * ___|___ ___|___ *
- * | | | | *
- * [0]<=[1] [0]>[1] [2]<=[4] [2]>[4] *
- * ① ② ③ ④ *
- * *
- * 情况①:[0][2]比较一次,[3][4]比较一次,即可确定顺序 *
- * 情况②:[0][4]比较一次,[0]<=[4]则[3][4]再比较一次 *
- * 情况③:[0][4]比较一次,[0]<=[4]则比较[0][2],否则比较[0][1] *
- * 情况④:[0][2]比较一次,[0]<=[2]则比较[0][4],否则比较[0][1] *
- * *
- * 伪代码如下: *
- * SORT([0],[1]); *
- * SORT([2],[3]); *
- * SORT([1],[3]); *
- * IF [1]<=[4] *
- * IF [0]<=[1] *
- * IF [0]<=[2] *
- * IF [3]<=[4] ① *
- * ELSE ② *
- * ELSE *
- * IF [3]<=[4] ③ *
- * ELSE ④ *
- * ELSE *
- * IF [0]<=[4] *
- * IF [3]<=[4] ⑤ *
- * ELSE ⑥ *
- * ELSE ⑦ *
- * ELSE *
- * IF [2]<=[4] *
- * IF [0]<=[4] *
- * IF [0]<=[2] ① *
- * ELSE ② *
- * ELSE *
- * IF [0]<=[1] ③ *
- * ELSE ④ *
- * ELSE *
- * IF [0]<=[2] *
- * IF [0]<=[4] ⑤ *
- * ELSE ⑥ *
- * ELSE *
- * IF [0]<=[1] ⑦ *
- * ELSE ⑧ *
- * 共15种情形,针对每种情形都可以有最佳移动顺序 0-8次,平均4.5次 *
- ********************************************************************/
- /*比较[0][1]*/
- if( arr[0] > arr[1])
- swap(arr[0],arr[1]);
- /*比较[2][3]*/
- if( arr[2] > arr[3])
- swap(arr[2],arr[3]);
- /*比较[1][3]*/
- if( arr[1] > arr[3])
- swap(arr[1],arr[3]);
- if( arr[1] <= arr[4] )
- {
- if( arr[0] <= arr[1])
- {
- if( arr[0] <= arr[2] )
- {
- if( arr[3] <= arr[4] )
- { /* ① 正确顺序为:[0][2][1][3][4]*/
- swap(arr[1],arr[2]);
- return 0;
- }
- else/*②正确顺序为:[0][2][1][4][3]*/
- {
- swap(arr[1],arr[2]);
- swap(arr[3],arr[4]);
- return 0;
- }
- }
- else/* arr[3] >= arr[1] >= arr[0] > arr[2] */
- {
- if( arr[3] <= arr[4])/*③正确顺序为:[2][0][1][3][4]*/
- {
- int temp = arr[2];
- arr[2] = arr[1];
- arr[1] = arr[0];
- arr[0] = temp;
- return 0;
- }
- else/*④正确顺序为:[2][0][1][4][3]*/
- {
- int temp = arr[2];
- arr[2] = arr[1];
- arr[1] = arr[0];
- arr[0] = temp;
- swap(arr[3],arr[4]);
- return 0;
- }
- }
- }
- else/* arr[1]<= arr[4] && arr[0] > arr[1] */
- {
- if( arr[0] <= arr[4])
- {
- if( arr[3] <= arr[4])/* ⑤正确顺序为[2][1][0][3][4]*/
- {
- swap(arr[0],arr[2]);
- return 0;
- }
- else/* ⑥正确顺序为[2][1][0][4][3]*/
- {
- swap(arr[0],arr[2]);
- swap(arr[3],arr[4]);
- return 0;
- }
- }
- else/* ⑦正确顺序为[2][1][4][0][3]*/
- {
- int temp = arr[4];
- arr[4] = arr[3];
- arr[3] = arr[0];
- arr[0] = arr[2];
- arr[2] = temp;
- return 0;
- }
- }
- }
- else/* arr[1] > arr[4] */
- {
- if( arr[2] <= arr[4] )/* [2][4][1][3]*/
- {
- if( arr[0] <= arr[4] )
- {
- if( arr[0] <= arr[2])/*①正确顺序为[0][2][4][1][3]*/
- {
- int temp = arr[4];
- arr[4] = arr[3];
- arr[3] = arr[1];
- arr[1] = arr[2];
- arr[2] = temp;
- return 0;
- }
- else/*②正确顺序为[2][0][4][1][3]*/
- {
- int temp = arr[4];
- arr[4] = arr[3];
- arr[3] = arr[1];
- arr[1] = arr[0];
- arr[0] = arr[2];
- arr[2] = temp;
- return 0;
- }
- }
- else
- {
- if( arr[0] <= arr[1] )/*③正确顺序为[2][4][0][1][3]*/
- {
- int temp = arr[4];
- arr[4] = arr[3];
- arr[3] = arr[1];
- arr[1] = temp;
- swap(arr[0],arr[2]);
- return 0;
- }
- else/*④正确顺序为[2][4][1][0][3]*/
- {
- int temp = arr[4];
- arr[4] = arr[3];
- arr[3] = arr[0];
- arr[0] = arr[2];
- arr[2] = arr[1];
- arr[1] = temp;
- return 0;
- }
- }
- }
- else/* [4][2][1][3] */
- {
- if( arr[0] <= arr[2] )
- {
- if( arr[0] <= arr[4] )/*⑤正确顺序为[0][4][2][1][3]*/
- {
- int temp = arr[4];
- arr[4] = arr[3];
- arr[3] = arr[1];
- arr[1] = temp;
- return 0;
- }
- else/*⑥正确顺序为[4][0][2][1][3]*/
- {
- int temp = arr[4];
- arr[4] = arr[3];
- arr[3] = arr[1];
- arr[1] = arr[0];
- arr[0] = temp;
- return 0;
- }
- }
- else
- {
- if( arr[0] <= arr[1] )/*⑦正确顺序为[4][2][0][1][3]*/
- {
- int temp = arr[4];
- arr[4] = arr[3];
- arr[3] = arr[1];
- arr[1] = arr[2];
- arr[2] = arr[0];
- arr[0] = temp;
- return 0;
- }
- else/*⑧正确顺序为[4][2][1][0][3]*/
- {
- int temp = arr[4];
- arr[4] = arr[3];
- arr[3] = arr[0];
- arr[0] = temp;
- swap(arr[1],arr[2]);
- return 0;
- }
- }
- }
- }