树的定义
树是一种数据结构,它是由n(n>=1)个有限结点组成的一个具有层次关系的集合
树的特点
- 每个节点有零个或多个子结点
- 没有父结点的节点称为根结点
- 每一个非根结点有且只有一个父结点
- 除了根结点,每个子结点可以分为多个不相交的子树
二叉树是每个结点最多有两个子树的树结构,通常子树被称作“左子树”和“右子树”,左子树和右子树同时也是二叉树。二叉树的子树有左右之分,并且次序不能颠倒。它有五种基本形态:空二叉树,只有一个根的二叉树,只有根和左子树的二叉树,只有根和右子树的二叉树,左子树和右子树和根都有的二叉树。
二叉树的性质
-
二叉树第i层上的结点数目最多为
-
深度为k的二叉树至多有个结点(k>=1)
-
包含n个节点的二叉树的高度至少为log2n+1
-
在任意一棵二叉树中,若终端结点的个数为n0,度为2的结点数为n2,则n0=n2+1
二叉树分为满二叉树、完全二叉树和二叉查找树
- 满二叉树:高度为h,并且由个结点组成的二叉树
- 完全二叉树:一棵二叉树中,只有最下面两层节点的度可以小于2,并且最下层的叶结点集中在靠左的位置上。叶子结点只能出现在最下层和次下层,且最下层的叶子结点集中在树的左部。如果一棵完全二叉树的结点总数为n,那么叶子结点等于n/2(当n为偶数时)或者(n+1)/2(当n为奇数时)
- 二叉查找树:又称为二叉搜索树。设x为二叉查找树中的一个结点,x结点包含关键字key,结点x的key值记为key[x]。如果y是x的左子树中的一个结点,则key[y]<=key[x];如果y是x右子树的一个结点,则key[y]>=key[x]
在二叉查找树中
- 若任意结点的左子树不空,则左子树上所有结点的值均小于它的根结点的值
- 任意结点的右子树不空,则右子树上所有结点的值均大于它的根结点的值。
- 任意结点的左、右子树也分别为二叉查找树。
- 没有键值相等的结点。
常见题型
1.求两个结点的最近公共祖先
求两个节点的最近公共祖先可分为三种情况,分别为:
(1)搜索二叉树,根据搜索二叉树的性质,左子树的所有节点比根节点小,右子树的所有节点比跟节点大。
如果两个节点都比根节点小,则递归左子树 ;
如果两个节点都比跟节点大,则递归右子树 ;
否则,两个节点一个在左子树,一个在右子树,则当前节点就是最近公共祖先节点。
2)三叉链,二叉树节点有指向父节点的指针。首先给出node1的父节点node1->_parent,然后将node1的所有父节点依次和 node2->parent作比较,如果发现两个节点相等,则该节点就是最近公共祖先,直接将其返回。如果没找到相等节点,则将 node2的所有父节点依次和node1->_parent->_parent作比较......直到node1->_parent==NULL。
(3)普通二叉树,这种情况可采用与搜索二叉树类似的解法
从根节点开始遍历,如果node1和node2中的任一个和root匹配,那么与root匹配的节点就是最低公共祖先。 如果都不匹 配,则分别递归左、右子树,如果有一个 节点出现在左子树,并且另一个节点出现在右子树,则root就是最低公共祖先. 如果两个节点都出现在左子树,则说明最低公共祖先在左子树中,否则在右子树。
树的遍历顺序大体分为三种:前序遍历(先根遍历、先序遍历),中序遍历(中根遍历),后序遍历(后根遍历)。
前序遍历:前序遍历可以记为根左右,若二叉树为空,则结束返回。
前序遍历的规则:
(1)访问根节点
(2)前序遍历左子树
(3)前序遍历右子树
这里需要注意:在完成第2,3步的时候,也是要按照前序遍历二叉树的规则完成。
中序遍历:中序遍历可以记为左根右,也就是说在二叉树的遍历过程中,首先要遍历二叉树的左子树,接着遍历根节点,最后遍历右子树。
同样,在二叉树为空的时候,结束返回。
中序遍历的规则:
(1)中序遍历左子树
(2)访问根节点
(3)中序遍历右子树
注意:在完成第1,3步的时候,要按照中序遍历的规则来完成。
后序遍历:后序遍历可以记为左右根,也就是说在二叉树的遍历过程中,首先按照后序遍历的规则遍历左子树,接着按照后序遍历的规则遍历右子树,最后访问根节点。
在二叉树为空的时候,结束返回。
后序遍历二叉树的规则:
(1)后序遍历左子树
(2)后序遍历右子树
(3)访问根节点
注意:在完成1,2步的时候,依然要按照后序遍历的规则来完成。