书的排序
来源:互联网 发布:蜻蜓fm 安卓网络错误 编辑:程序博客网 时间:2024/06/06 07:11
http://www.matrix67.com/blog/archives/3066/comment-page-1
书架的某一层里放了一套百科全书,但它们排列的顺序却是乱的。一个傻子想要把这套书排好顺序,也就是说他想要书架里的书从左至右分别是第 1 卷,第 2 卷,……,第 n 卷。他给这套书排序的办法是这样的:不断取出一本原应放在更左边的书,插进它该在的位置。比方说,某本书的卷号是 3 ,它的位置却是左起第 5 ,位于其目标位置的右侧。那么傻子就可以把这本书拿出来,插入当前左起第 2 本书的右边,把那些占了它位置的书挤到更右边去,而不管这一操作是否会破坏掉已经就位的书。注意到这种排序法很可能捡了芝麻,丢了西瓜,为了一本书的位置而破坏掉一连串原已排好的书,可谓是鼠目寸光,缺乏远见。我们的问题是,在哪些情况下这样的排序法最终一定能实现排序,哪些情况下可能会陷入永无止境的死循环?
出人意料的是,这种看上去明显有漏洞的排序法竟然是一种正确的排序算法——对于任意一个初始序列,采用这种方法总能让序列最终变得有序。为了证明这一点,我们按照如下方式把序列编码为 n 位的 01 串:左起第 i 位为 1 当且仅当第 i 卷在正确的位置上。序列 7, 2, 1, 4, 3, 5, 6, 8, 9 就被编码为 010100011 ,因为在这 9 本书当中,只有卷 2 、卷 4 、卷 8 和卷 9 在正确的位置上。
如果某一次操作中,傻子把第 k 卷放进了正确的位置,那么考虑所有卷数小于 k 的书:如果它原本就在左起第 k 本书的左边,这个操作影响不到它;如果它原本就是左起第 k 本或者更右边的书(这表明它原本就不在正确的位置上),那么现在它仍然不可能在正确的位置上(它的位置只可能不变或者更靠右了)。因此,编码的前 k-1 位是不动的,但第 k 位从 0 变成 1 了。这就意味着,任意一个操作总会让整个二进制编码变大。而容易看出,只要序列不是有序的,傻子总有可以操作的对象,因此序列编码将不断增加,最终将变成 111...11 。此时所有书都在它应该在的位置上,整个序列也就有序了。
现在,又来了另外一个傻子。他的排序办法和前一个傻子基本上相同,唯一不同的是,他每次都可以选择任意一本不在原位的书(并把它放进它应该在的位置),而不仅仅是选择那些位于目标位置右侧的书。这个傻子的排序方法还能保证最终总会让这排书变得有序吗?
答案竟然再一次是肯定的——这种方法最终总能让所有序列变得有序。为了证明这一点,只需要注意到,只要序列不是有序的,傻子总能找到合法的操作,因此只要不存在循环,序列最终一定会变得有序。我们将用反证法证明,傻子的操作一定不会让状态产生循环。
假设存在一个循环,并且在某一步,傻子取出了第 k 卷,并且无妨假设它被移动到了更右边的某个位置。由于这是一个循环,因此在某个时候它又跑回了目标位置的左边。这说明,傻子一定取出了一本卷号比 k 更大的书,放到了 k 的右边,并把 k 挤到左边去了。只需要令 k 为循环中被挪到右边的书中卷号最大的一本,矛盾就产生了。
- 书的排序
- 【排序】排序的基本概念
- 数组的排序:冒泡排序、选择排序
- 常用的排序算法:插入排序,希尔排序,冒泡排序,选择排序,快速排序,归并排序
- 单链表的排序(选择排序)
- 排序的之插入排序
- 简单的排序---选择排序
- 简单的排序---插入排序
- 简单的排序---堆排序
- 不是快速排序的排序
- 【排序】链表上的归并排序
- 堆排序 - 不稳定的排序
- 排序:一些排序的总结
- 有趣的排序-百度-排序
- 三种最基本的排序 选择排序 插入排序 冒泡排序
- java数组的排序,选择排序,冒泡排序,插入排序
- 【复赛模拟试题】书的排序
- 基本的排序算法:冒泡排序、插入排序、希尔排序、选择排序、归并排序、快速排序、堆排序
- 念,心随君浅舞天涯
- BulletPhysics,RigidBody and soft body Interface <2>
- makefile编写(3)
- 查阅项的赋值和查看
- hdu1754 求区间最值 线段树 树状数组
- 书的排序
- Java回调函数的理解
- 正则表达式常见的一些符号含义
- 26个Jquery使用小技巧
- sqlite之我见--C/C++ API接口示例
- 杭州ADC技术嘉年华两日总结-SOA,去C
- 生命的节日
- Spring,hibernate,struts的面试笔试题
- 华为任正非与2012实验室座谈会纪要- 看看中国最一流的企业家的战略思维