与树相关的知识点:
相对来说清华大学出版社的这本《离散数学》有关树的这一章节还是比较简单地,概念也不多,有关树、森林、树叶、分支点、生成树、最小生成树等概念都很简单,这里不再累述,下面记录几个定理和重要的算法步骤。
定理1:设T<V,E>是n阶非平凡的无向树,则T至少有2片树叶。
证明:设T有k片树叶,则有n-k个分支点(分支点的度数大于等于2),由握手定理可知2m≥k + 2(n-k),然后考虑到树结构中一个非常常用的性质,边数m和顶点数n满足m = n – 1,带入不等式,可得k≥2,证毕。
这里有一组概念可能会比较生疏:树的树枝和弦,即对于G的生成树T,属于G也属于T的边称为T的树枝,属于G但是不属于T的边称为T的弦。
定理2:任何无向连通图G都存在生成树。
证明:如果G不存在回路,那么G是树;如果G存在回路,那么去掉这个回路当中任何一条边,使其不成回路但并没有影响G的连通性,反复操作,必然会得到一棵没有回路的图G,即得到一棵生成树。
基于贪心的Kruskal算法和Huffman算法:
它们都基于一种基本的算法思想——贪心。这种思想有些玄妙用语言表述起来并不简便,因此这里不体现证明。(笔者在一篇有关贪心法的文章中曾尝试给出哈夫曼算法的证明,如果读者感兴趣可以去看一看)
Kruskal算法(最小生成树):
将G中m条边的权值进行从小到大排序e1,e2,e3,…,em,基于n阶零图,然后从e1开始选边构造,如果选入ei导致当前图出现回路,则放弃这条边。
Huffman(最优二元树):
给定实数w1、w2、w3…wt,作为二元树t片叶子的权值。
(1) 将t个权值按上升排序。
(2) 选取权值序列最小的两个wi、wj,合成一个分支点,权值为wi+wj,将wi、wj从权值序列中删除,并添加新权值wi+wj。
(3) 重复(2),知道权值序列为空。
Huffman算法的一个生活应用:最优前缀码。
下面来介绍树结构中比较生疏的几组概念:
根树:基于有向图中的树结构。
r元树:每个分支点至多有r个儿子的树。
r元正则树:每个分支点都是有r个儿子的树。
r元完全正则树:基于r元正则树,所有叶子的树高相同的树结构。
有序树:对于根树,规定了每一层节点的顺序的树结构。
根树周游:按照访问树根的先后,这里有中序、前序、后序行遍三种方法,理解它们定义的关键是搞懂这是一个递归过程。
根树周游的一个应用:波兰符号。