【算法设计与分析】5个数7次比较排序的算法

找到最快的算法,一直是计算机界的目标之一,而排序就是其中最基本的算法。什么样的排序才是最快的呢?

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

上述程序,我应经做了简单的测试,没有发现bug,比较的思想在注释中进行了详细说明。有人说,优秀的程序员都有完美情节,我们看到追求完美的带价的高昂的,程序显得异常复杂。但也正是这种不断追求完美的勇气,才让这个世界越来越美好,越来越丰富多彩,不是吗?


你可能感兴趣的:(算法,排序)