目录(点击切换)
本文节选自《计算之魂》电子版:
1/计算之瑰//先说说几种常见的复杂度为OUV)的排序算法,我们会重点分析这类算法的时间浪费在哪里了。拥有了找出无用功的能力,你就能做成他人做不到的事情。不失一般性,我们在这本书中都假设做从小到大的排序,除非在某些场合要做相反的排序,那时我们会特别说明。1.4.1直观的排序算法时间到底浪费在哪里假定序列有六个元素,存于一个数组ac[IM]中。我们要讲的第一种排序算法是选择排序(SelectionSort),它每一次从序列中挑出一个最大值,放在序列的最后,这样重复多次扫描序列后,整个序列就排序完毕,具体做法如下。步骤1,从头到尾(《即关1~N)比较相邻的两个元素<国和al+l。如果四和at+1],不做任何处理;反之,将a[]和a[i+1]元素值互换,也就是说,小的放前面,大的放后面。这样一个一个互换,到了数组的未尾时,最后一个一定是最大的。这个元素就如同水中的气泡一样,不断上升,直到冒出头。这一遍从头到尾的扫摘,进行了AM-1次的比较和少于Ar!1次的互换。步骤2,我们再从头到倒数第二个元素,即第NI个元素,重复上述过程。每一次扫描,会从剩余的元素中找到其中最大的。当我们完成第大遍扫描时,最后天个元素已经排好序了。因此,对于有N个元素的数组,我们只需要扫描六次,每一次比之前少一个元素。这样整个算法的复杂度就是(W-
计算之魂内容概括
D+(N-2+(W-3)+…+1=之人选择排序给人的直观感觉是非常策,我们甚至可以讲它是“最坏”的排序算法。因为在六个元素中选出最大的〈或者最小的)至多进行OUV)次操作,而整个数组最多这样操作X次,也必然排好序了。因此OCV)是排序算法的上界了。那么接下来的问题是如何改进排序算法。很多人直观的感觉是,“如果让我来排序,不需要做那么多无用的工作,我直接=O(N)。046//第1章//毫厘干里之差一一大O概念//将小的数字插入数组的前面,大的插入后面,因此扫描完一遍数组,就应该能够排好序了。这就好比打扑克牌时的抓牌过程,一边抓牌,一边将新抓起的牌插入相应的位置。排序的次数和抓牌的次数相同。这种直觉其实正好对应于一种计算机的排序算法,即我们要介绍的第二种排序算法一一插入排序(InsertSort)。插入排序的过程和抓牌、插牌很相似。对于未排序数组,我们不断从后向前扫描,这就相当于从后向前摸牌,对于每一个拿到手上的元素,我们找到相应的位置插入。最后所有的元素扫描一遍,全部插入相应的位置,也就实现了排序。这种算法看上去只扫描了一遍数据,但是复杂度依然是OO,完全没有降下来。为什么会是i个结果呢?我们不妨看看一个规范化后的插入排序过程。首先,我们把最后一个元素*[M]拿出来,和第一个元素a[1]比较,比<[1]小就放在a[
吴军新书计算之魂
1]的前面,比a[1]大就放在a[1]的后面,成为数组中的第二个元素。这时,这两个元素排好了序。不过,上述操作在完成之前需要做一个准备工作,就是在a[]之前,或者c[1]和a[2]之间给新插进来的元素aLN]留一个空位。摸扑克牌、插扑克牌没有这个问题,直接把牌插入即可,但是数组中的元素是一个连着一个存放的,中间没有空位。因此,要给新来的元素腾地方,就要把所有的元素往后挪。于是,这样一来插入一个元素的操作就不是一次了,而是CO(N)次。接下来插入第二个元素,也就是元素<LY-1]。我们知道经过上一步之后,前两个元素已经排好序了,于是我们就用LN-1]和排好序后的两个元素做对比,找到它的位置《有三种可能性,要么在最前面,要么在两个元素之间,要么在两个元素之后),然后再将自a[3]往后所有的元素向后平移一个位置,腾出地方插入a[N-1]。这个步又还是OOV次操作。此后,我们不断重复上述过程,每一次可以排好一个数,直到整个序列都变得有序。很显然,这个算法的复杂度就是OOV),不比选择排序更好。虽然在上述过程中,找到插入的位置可以采用二分查找,在logX的时间内完成,但是挪动元素的时间省不了,最糟糕的情况是插入一个元素,要挪动Ar-1个元素。关于二分查找,我们后面会讲,这里大家只要记住它在一个排好序的序列中找到一个047
计算之魂百科
| 计算之魂介绍 | 计算之魂吴军下载 |
| 计算之魂电子书下载 | 计算之魂内容 |
| 计算机之魂 | 吴军计算之魂的主要内容 |
综上:计算之魂内容值得推荐阅读

评论已关闭!