【算法设计与分析】5个数7次比较排序的算法
2016-06-15 00:00
239 查看
找到最快的算法,一直是计算机界的目标之一,而排序就是其中最基本的算法。什么样的排序才是最快的呢?
1.最少的比较次数,算法理论证明n个数排序,如果是基于比较的算法,至少需要 ㏒(n!) 向上取整数。下面给出小数目下,最少比较次数:
2.移动次数最少,根据群论置换群理论,n个数的序列,变换到这n个数组成另一个序列,一定可以在最多n次移动内做到。
在理论的指引下,人们开始寻找这些传说中的极限。人们开始简单地完成了n=1,2,3,4的极限算法,但是当n=5时,人们长期停留在了8次比较。但是在1956年,H.B.Demuth在终于首先找到5个次7次比较的排序方法,并在他的博士论文中进行了阐述。下面就是对这个算法的C语言实现:
上述程序,我应经做了简单的测试,没有发现bug,比较的思想在注释中进行了详细说明。有人说,优秀的程序员都有完美情节,我们看到追求完美的带价的高昂的,程序显得异常复杂。但也正是这种不断追求完美的勇气,才让这个世界越来越美好,越来越丰富多彩,不是吗?
1.最少的比较次数,算法理论证明n个数排序,如果是基于比较的算法,至少需要 ㏒(n!) 向上取整数。下面给出小数目下,最少比较次数:
n | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
㏒(n!) | 0 | 1 | 3 | 5 | 7 | 10 | 13 | 16 |
在理论的指引下,人们开始寻找这些传说中的极限。人们开始简单地完成了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,比较的思想在注释中进行了详细说明。有人说,优秀的程序员都有完美情节,我们看到追求完美的带价的高昂的,程序显得异常复杂。但也正是这种不断追求完美的勇气,才让这个世界越来越美好,越来越丰富多彩,不是吗?
相关文章推荐
- 深度学习在自然语言处理相关文章
- 25个Java机器学习工具&库
- 深度学习在自然语言处理的应用
- ORA-01720
- NLP好文章
- 机器学习中防止过拟合的处理方法
- Deep Learning及NLP(自然语言处理)杂谈--第一部分
- 从头开始实现神经网络:入门
- Stanford CoreNLP开源项目的3种编译和运行方式[1]
- LSTM简介以及数学推导(FULL BPTT)
- 消息订阅发布系统Apache Kafka分布式集群环境搭建和简单测试
- 【深度学习】卷积神经网络(Convolutional Neural Network)
- 深度学习(DL)与卷积神经网络(CNN)学习笔记随笔-01-CNN基础知识点
- Word Embedding的通俗解释
- 人工神经网络的深入理解
- Google-hosts
- 视频+代码+资料:Nils Reimers面向NLP的深度学习(Theano/Lasagne)系列教程
- 自然语言处理(NLP)网上资源整理
- Memcached集群/分布式的单点故障
- 语义分析的一些方法(下篇)