二叉树

title: 图论中的定义.
content: 二元树是一个连通的无环图,并且每一个顶点的度不大于3。有根二元树还要满足根节点的度不大于2。有了根节点之后,每个顶点定义了唯一的父节点,和最多2个子节点。然而,没有足够的资讯来区分左节点和右节点。如果不考虑连通性,允许图中有多个连通分量,这样的结构叫做森林。
title: 性质.
content: 二元树是一个有根树,并且每个节点最多有2个子节点。非空的二叉树,若树叶总数为 n0,分支度为2的总数为 n2,则 n0 = n2 + 1。
title: 特殊类型.
title: 满二叉树.
content: 一棵深度为k,且有formula_4个节点的二元树,称为满二元树(Full Binary Tree)。这种树的特点是每一层上的节点数都是最大节点数。
title: 完全二叉树.
content: 而在一棵二元树中,除最后一层外,若其余层都是满的,并且最后一层或者是满的,或者是在右边缺少连续若干节点,则此二元树为完全二元树(Complete Binary Tree)。具有n个节点的完全二元树的深度为formula_15。深度为k的完全二元树,至少有formula_16个节点,至多有formula_4个节点。
title: 存储.
content: 在程序设计语言中能用多种方法来构造二元树。
title: 顺序存储表示.
content: 二元树可以用阵列或链接串行来存储,若是满二元树就能紧凑排列而不浪费空间。如果某个节点的索引为i,(假设根节点的索引为0)则在它左子节点的索引会是formula_18,以及右子节点会是formula_19;而它的父节点(如果有)索引则为"formula_20"。这种方法更有利于紧凑存储和更好的访问的局部性,特别是在前序遍历中。然而,它需要连续的存储空间,这样在存储高度为"h"的"n"个节点所组成的一般树时,将浪费很多空间。在最糟糕的情况下,如果深度为h的二元树其每个节点都只有右孩子,则该存储结构需要占用formula_21的空间,实际上却有h个节点,浪费了不少空间,是顺序存储结构的一大缺点。
title: 二叉链表存储表示.
content: 在使用记录或内存位址指标的程序设计语言中,二叉树通常用树结点结构来存储。有时也包含指向唯一的父节点的指标。如果一个结点的子结点个数小于2,一些子结点指针可能为空值,或者为特殊的哨兵结点。 使用链表能避免顺序储存浪费空间的问题,算法和结构相对简单,但使用二叉链表,由于缺乏父链的指引,在找回父节点时需要重新扫描树得知父节点的节点位址。
title: 三叉链表存储表示.
content: 改进于二叉链表,增加父节点的指引,能更好地实现节点间的访问,不过算法相对复杂。 当二叉树用三叉链表表示时,有N个结点,就会有N+2个空指针。
title: 遍历.
content: 我们经常希望访问树中的每一个结点并且查看它的值。有很多常见的顺序来访问所有的结点,而且每一种都有有用的性质。
title: 深度优先遍历.
content: 在深度优先级中,我们希望从根结点访问最远的结点。和图的深度优先搜索不同的是,不需记住访问过的每一个结点,因为树中不会有环。前序,中序和后序遍历都是深度优先遍历的特例。
title: 前(先)序、中序、后序遍历.
content: 遍历二叉树:L、D、R分别表示遍历左子树、访问根结点和遍历右子树,则先(根)序遍历二叉树的顺序是DLR,中(根)序遍历二叉树的顺序是LDR,后(根)序遍历二叉树的顺序是LRD。还有按层遍历二叉树。这些方法的时间复杂度都是O(n),n为结点个数。  如果T2是由有序树T转换而来的二叉树,那么T中结点的前序就是T2中结点的前序,T中结点的后序就是T2中结点的中序。任何一棵二叉树的叶结点在先序、中序和后序遍历中的相对次序不发改变。设n,m为一棵二叉树上的两个结点,在中序遍历时,n在m前的条件是n在m的左方。前序序列和中序序列相同的二叉树为空树或任一结点均无左孩子的非空二叉树;中序序列和后序序列相同的二叉树为空树或任一结点均无右孩子的非空二叉树;前序序列和后序序列相同的二叉树为空树或仅有一个结点的二叉树。  假设我们有一个包含值的codice_1和指向两个子结点的codice_2和codice_3的树结点结构。我们可以写出这样的过程:  这样会用前序打印出树中的值。在前序,每个结点在访问它的子结点之前访问。类似地,如果打印语句在最后,每个结点在访问他的子节点之后访问,树中的值会用后序来打印。在这两种情况中,左子树中的值比右子树中得值先打印。  最后,上面的中序遍历,每个结点在访问左子树和右子树之间访问。这在遍历二叉搜寻树时很常用,因为它能用递增的顺序来遍历所有的值。  为什么呢?如果"n"是二叉搜寻树的结点,那么"n"的左子树的所有结点的值都比n的值要小,而且"n"的右子树的所有节点的值都比n的值要大。因此,如果我们顺序遍历左子树,然后访问"n",然后顺序遍历右子树。我们就已经循序存取了整个树。  后序遍历伪代码如下:  以上的递回算法使用与树的高度成比例的栈空间。如果我们在每个结点中存储指向父结点的指标,那样可以使用反复运算算法,只使用常数空间实现所有这些遍历。然而,指向父结点的指标占用更多的空间。这只在需要指向父节点的指标或栈空间有限时才使用。例如, 这是一个中序遍历的反复运算算法:
title: 广度优先遍历.
content: 和深度优先遍历不同,广度优先遍历会先访问离根节点最近的节点。二叉树的广度优先遍历又称按层次遍历。算法借助伫列实现。
title: 转换自多叉树.
content: 一般有序树可映射为二叉树,但反之未必成立。  n叉树转换为二叉树的方法:二叉树中结点x的左子结点为n叉树中结点x的左子结点;二叉树中结点x的右子结点为n叉树中结点x的第一个右边的同级结点y。  二叉树当且仅当根节点没有右子结点时可转换为n叉树。 例如,在左边的树中,A有6个子结点{B,C,D,E,F,G}。它能被转换成右边的二叉树。
title: 树的二叉链表标记法(孩子兄弟标记法).
content: 树的二叉链表标记法(孩子兄弟标记法)是树和二叉树转换的媒介。
title: 线索二叉树.
content: 线索二叉树(英语:threaded binary tree,保留遍历时结点在任一序列的前驱和后继的资讯):若结点有左子树,则其lchild域指示其左孩子,否则令lchild域指示其前驱;若结点有右子树,则其rchild域指示其右孩子,否则令rchild指示其后继。还需在结点结构中增加两个标志域LTag和RTag。LTag=0时,lchild域指示结点的左孩子,LTag=1时,lchild域指示结点的前驱;RTag=0时,rchild域指示结点的右孩子,RTag=1时,rchild域指示结点的后继。以这种结点结构构成的二叉链表作为二叉树的存储结构,叫做线索链表,其中指向结点前驱和后继的指标叫做线索,加上线索的二叉树称为线索二叉树。对二叉树以某种次序遍历使其变为线索二叉树的过程叫做线索化。若对二叉树进行中序遍历,则所得的线索二叉树称为中序线索二叉树,线索链表称为为中序线索链表。线索二叉树是一种物理结构。 在中序线索树找结点后继的规律是:若其右标志为1,则右链为线索,指示其后继,否则遍历其右子树时访问的第一个结点(右子树最左下的结点)为其后继;找结点前驱的规律是:若其左标志为1,则左链为线索,指示其前驱,否则遍历左子树时最后访问的一个结点(左子树中最右下的结点)为其前驱。 在后序线索树中找到结点的后继分三种情况:
title: 二叉线索存储表示.
title: 存储结构.
content: 二叉树的二叉线索存储表示:在线索链表上添加一个头结点,并令其lchild域的指标指向二叉树的根结点,其rchild域的指标指向中序遍历时访问的最后一个结点。令二叉树中序序列中的第一个结点的lchild域指标和最后一个结点的rchild域的指标均指向头结点,这样就建立了一个双向线索链表。二叉树常采用二叉链表方式存储。

Summary: 在电脑科学中,二元树(英语:Binary tree)是每个节点最多只有两个分支(即不存在分支度大于2的节点)的树结构。通常分支被称作“左子树”或“右子树”。二元树的分支具有左右次序,不能随意颠倒。

Binary tree: In computer science, a binary tree is a tree data structure in which each node has at most two children, which are referred to as the'and the '. A recursive definition using just set theory notions is that a (non-empty) binary tree is a tuple ("L", "S", "R"), where "L" and "R" are binary trees or the empty set and "S" is a singleton set. Some authors allow the binary tree to be the empty set as well.