《数据结构与算法分析》5000字缩写(上)

    4月7日买起来看,前几天才看完。这可以说明很多问题,比如,学习很紧张,没有时间;书本身很好,很有看头;看书看得很细心,很有耐心。
    打算大致写一下书里的内容。
    Data Structures and Algorithm Analysis in C, Second Edition,机械工业出版社。封面很丑,一个黑底版,上面有些大理石花纹,正中间生硬的摆一个原版封面,同样丑。一共12章,近400页。
    400多页是很多的。我们必须要“把厚书读薄”,厚的变薄的,薄的变一页,一页变一行,一行变成一个字。因此,我要在有限的字数内把整本书说完。

    算法分析,就是复杂度的问题。复杂度只算“最要命的”,比如,执行n^2的算法前来个快排根本不拖速度,n^2多的都豁出去了不在乎区区一个nlogn。书里对复杂度进行了严格的定义,包括O()、o()、Θ()、Ω()四种符号。简单地说,O(n^2)就是顶破天了搞个n^2次;o(n^2)就是天花板不到n^2,比n^2矮一点(比如希尔排序就是o(n^2),因为它再倒霉也达不到n^2);Ω(n^2)就是说某个算法随便怎么至少都要耗费n^2,比如所有基于比较的排序都是Ω(nlogn);Θ(n^2)就是说它即是O(n^2)又是Ω(n^2),被天花板和水泥地夹在中间了,动不了了,就是它了。这里面有一个经典的例子,就是最大子序列(找数列中连续一段数之和最大)的四种算法,复杂度分别为O(n^3)、O(n^2)、O(nlogn)和O (n)。这书一个特色在于,对每种数据结构都有严格的算法复杂度证明,这往往是看上去最头痛的部分。

    表、栈和队列是三个基本的数据结构。说穿了表就是把数据找起来排排坐吃果果,找什么东西都来把整个队伍找一遍。栈就是一个桶,后放进去的先拿出来,它下面本来有的东西要等它出来之后才能出来,就好像你看到了一个丑人不可能今天的中饭还没吐出来就先把早饭吐出来了。栈是拿来模拟多个过程的调用的(比如递归),实际点的用途就是表达式计算。队列好比堵车,先进去的先出来。先进队先买票,不能插队。常拿来实现广搜。

    树,是一种植物,有很多枝枝丫丫。不同的是这里的树是倒着的,树枝朝下长。最上面叫根,尖尖的地方叫树叶,生出树叶的是他爸,他爸生的是他儿子。不管是根是树叶还是儿子还是儿子他爸都叫节点。我们常常把数据储存在节点上,并且以后还要不断地插入、改变和删除数据。
    二叉树就是每个分叉的地方最多分两个岔,而且还分得清左右。二叉查找树就是说把数据存在节点上,而且左边的都比他爸小,右边的都比他爸大,以后要找哪个数就可以只找其中的一边,一半一半地扔掉。在二叉查找树里也可以插入一个数,删掉一个数(只有一个儿子好办,有两个就把右边的最小的一个拿来替代这个),找最小的数(一直往左走),找最大的数(一直往右走),但是容易搞着搞着的树就变畸形了,比如说左边猛起长右边萎缩导致以后往左边走要走很久。我们就需要一种方法来让树左右差不多一样多而且左边的值仍然比右边的小。事实上这种方法已经找到了,而且不只一种方法,而是一卡车的方法,比如AVL、Splay、红黑树、Treap等。几种方法都靠一个叫“旋转”的技巧,就是把几个节点怎么个一转,左边的就跑到右边去了一点。看下面这个图你就明白了。

         ①                   ②
        /        旋转       /  
      ②   ZZ    ——>    XX  ①
     /                        /  
    XX  YY                    YY  ZZ

这样一来左边就少了,如果左边的XX本来很多的话就可以往上提一层从而平衡。同样地,右边多了反过来做就是了。这只是最简单的“单旋转”,事实上还有很多其它的较复杂的旋转方法。Splay树就是把刚才访问过的节点转啊转啊转啊转转到最顶上去,Treap就是每个节点附加一个随机的数,随时通过旋转保持儿子的这些随机数比他爸大,其余的有点复杂。这些方法都能使二叉查找树相对地平衡一些,防止畸变导致的时间浪费。
    B-树和二叉查找树有两个不同,一个是节点不存数据,数据全在树叶子上,二个是它不一定是二叉。数据仍然左边小右边大方便查找。每个节点最多的儿子数有限制,最多三叉的叫2-3树,最多四叉的叫2-3-4树。因为只有树叶上有数据,所以可以递归地用分裂的方法处理新插入后出现的分叉比规定的最多的儿子个数时还多的情况。比如,2-3树中如果哪里分了四个岔,就把它重新分成两个两个的岔。我们还规定,除了根以外,每个节点最少的儿子数是规定的最多儿子数的一半,除不尽取上整。容易想到,删除的话可以把插入时的分裂反过来做,什么时候只剩一个儿子了就和旁边的合并起来。

    Hash表又叫散列表,一般用于判断有没有重复。比如我想找我们班有没有两个一天生的,我们不必每两个人都来比较一次,而是准备一个年历,让人一个一个上去在他的生日那天那里画一个圈,如果谁要画圈时发现那里已经有一个圈了,就找到了一对。这个很简单,不说了。
    那天班上流行一个心里测试,当时我还真发现了一个和我一天生的,女的。

Matrix67原创
做人要厚道 转帖请注明出处

21 条评论

发表评论