目录
二叉树的定义:
二叉树相关术语:
二叉树的概念与性质
二叉树基本性质
二叉树的节点数量
满二叉树概念:
完全二叉树概念:
完全二叉树性质:
二叉树的存储
二叉树的遍历
在此基础上,二叉树的遍历又分为以下三种:
先序遍历
中序遍历
二叉树遍历的总结
二叉树的遍历转化
二叉树的特殊遍历方法
特殊的二叉树
二叉搜索树
平衡二叉树
总结:
一、二叉树的概念与性质
二、二叉树的储存与遍历
二叉树的定义:
二叉树(binary tree)是指树中节点的度不大于2的有序树,它是一种最简单且最重要的树。二叉树的递归定义为:二叉树是一棵空树,或者是一棵由一个根节点和两棵互不相交的,分别称作根的左子树和右子树组成的非空树;左子树和右子树又同样都是二叉树【节选自百度】
节点 | 左子树 | 右子树 |
0 | 子树 1 | 子树 7 |
1 | 子树 2 | 子树 6 |
2 | 无 | 无 |
链表也可以看作是一棵特殊的二叉树,因为链表每个结点只有一个子节点,满足二叉树的定义。二叉树与普通树的差别在于,普通树可以有 2 个以上的子节点,而二叉树的子节点不能超过 2 个。
链表 | 二叉树 | 树 | |
后继节点 | 1个 | 不超过 2个 | 任意个 |
定义关系 | 链表属于二叉树 | 二叉树属于树 |
二叉树相关术语:
- 节点:包含一个数据元素及若干指向子树分支的信息 。
- 节点的度:一个节点拥有子树的数目称为节点的度 。
- 叶子节点:也称为终端节点,没有子树的节点或者度为零的节点。
- 分支节点:也称为非终端节点,度不为零的节点称为非终端节点 。
- 树的度:树中所有节点的度的最大值。
- 节点的层次:从根节点开始,假设根节点为第1层,根节点的子节点为第2层,依此类推,如果某一个节点位于第L层,则其子节点位于第L+1层 。
- 树的深度:也称为树的高度,树中所有节点的层次最大值称为树的深度 。
- 有序树:如果树中各棵子树的次序是有先后次序,则称该树为有序树。
- 无序树:如果树中各棵子树的次序没有先后次序,则称该树为无序树。
- 森林:由m(m≥0)棵互不相交的树构成一片森林。如果把一棵非空的树的根节点删除,则该树就变成了一片森林,森林中的树由原来根节点的各棵子树构成。
二叉树的概念与性质
二叉树限定了孩子个数最多为2,而正是由于这种限定,使得二叉树拥有许多性质。
二叉树基本性质
性质1:在二叉树的第i层上最多有2i-1个结点(i>=1)。
性质2:深度为k的二叉树至多有2k–1个结点(k>=1)。
性质3:对任意一棵二叉树,如果其叶结点数为n0,度为2的结点数为n2,则一定满足:n0=n2+1。
归纳法证明性质3
假设初始为一个两个节点的二叉树。此时n0=n2+1,此时加点有两种方式:
1.加到叶节点,此时n0,n2不变
2.加到只有一个儿子的节点上,此时n0+1,n2+1。同样满足n0=n2+1
如果我们保证前面若干层都是满节点,那么我们就可以知道前面第i层确定的节点个数,这样的树将拥有更多的性质。
二叉树的节点数量
一棵高度为n的二叉树,最多包括2n−1个节点。树高为n,共有n 层,第一层有1 个根节点,根据二叉树的定义,后面每层节点的数量最多为上一层的2 倍,因此最多有:1+2+4+....+2n−1=2n−1个节点。
那么一棵高度为n的二叉树,最少有 n 个节点,是一个链表。
考虑前若干层是否为满节点,我们有两种特殊的二叉树:满二叉树和完全二叉树
满二叉树概念:
一棵深度为k且有2k–1个结点的二叉树 称为满二叉树。 通常来说我们对满二叉树的结点进行 连续编号,约定从根结点起,自上而 下,从左到右进行编号。
完全二叉树概念:
深度为k,有n个结点的二叉树当且 仅当其每一个结点都与深度为k的满 二叉树中编号从1到n的结点一一对 应时,称为完全二叉树。 特点:k-1层以前是满二叉树,最后 一层节点从左到右连续出现。
完全二叉树性质:
性质1:具有n个结点的完全二叉树的深度为:floor(log2n)+1
性质2:对于一棵n个结点的完全二叉树,对任一个结点(编号为i),有:
1) 节点i的左儿子为:i*2,节点i的右儿子为:i*2+1。
2) 若i*2+1>n,说明节点i无右儿子。若i*2>n,说明节点i无儿子。
3) 对于节点i,若i>1,则节点i的父亲为:i/2。
二叉树的存储
对于一颗普通的树,我们采取vector存放儿子,但是对于二叉树,我们只需要记录左右儿子即可。
有数组存放和结构体存放两种方式。结构体存放会更耗空间,因为结构体内部有不定长度的动态数组。 而存放二叉树,只需要用ls,rs来存放左右儿子即可。 空间占用与普通数组一样。对于复杂题目,信息较多的时候,变量命名更轻松,信息也独立。同时为了更快速调用,可以在结构体内进行define。
struct node{
int value;
vector<int> childs; //用来记录所有子节点的编号
}nodes[10000];
int root;
//root为根节点
也可以利用二叉树的特性,用左右子树的方式,来存储二叉树。
用结构体来表示二叉树的节点, 每个节点存储了当前节点的值, 以及左子树和右子树的编号。
struct node{
int value;
int left;
int right;
}nodes[10000];
int root; //root为根节点
二叉树的遍历
遍历二叉树的方法可以沿用遍历树的方法——递归。
DFS(当前节点u){
DFS(u.left);
DFS(u.right);
}
在此基础上,二叉树的遍历又分为以下三种:
先序遍历
遍历顺序规则为:根左右,遍历方法:
(1)访问根节点
(2)采用先序递归遍历左子树
(3)采用先序递归遍历右子树
中序遍历
遍历顺序规则为:左根右,遍历方法:
(1)采用中序遍历左子树
(2)访问根节点
(3)采用中序遍历右子树
二叉树遍历的总结
三种方法遍历过程中经过节点的路线一样,只是访问各个节点的顺序不同。
二叉树的先序、中序、后序遍历我们已经学会了, 那么给定其中任意两种遍历, 我们能否推出唯一的第三种遍历么?
答案:给定先序+中序可以推出后序。后序+中序可以推出先序。但是先序+后序是无法推出中序的。
这里我们只是以:知道先序遍历和中序遍历,推断后序遍历作为例子,其他组合方式原理是一样的。
二叉树有以下几种特性:
特性 A ,对于先序遍历,第一个肯定是根节点
特性 B ,对于后序遍历,最后一个肯定是根节点
特性 C ,利用先序或后序遍历,确定根节点,在中序遍历中,根节点的两边就可以分出左子树和右子树;
特性 D ,对左子树和右子树分别做前面 3 点的分析和拆分,相当于做递归,我们就可以重建出完整的二叉树。
所以我们可以靠保存先序+中序,或者后序+中序 2 个顺序,来保存整个二叉树的结构。
二叉树的遍历转化
一颗二叉树如果知道中序遍历,以及先序(或后序),我们就能清晰的知道树的结构
二叉树的特殊遍历方法
对于一棵二叉树,由于其特殊的性质,我们在树上信息统计的时候有其独特的方法。
二叉树的特殊遍历方法 前面所学并查集中提到,若没有查询某个节点,节点上的信息可以暂时不更新,等到需要的时候我们再去更新。在二叉树中,应用得也比较广泛,我们称之为”懒标记“。
如图:若某点值若只与父亲节点相关,修改7号节点的时候,只影响其本身的值,其他节点可以正常访问。当我们需要访问到该节点的时候,再进行更新。这样,我们可以将多次修改放到一起解决,从而降低问题的复杂度。
特殊的二叉树
二叉搜索树
二叉搜索树( Binary Search Tree )它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有节点的值均小于它的根节点的值; 若它的右子树不空,则右子树上所有节点的值均大于它的根节点的值; 它的左、右子树也分别为二叉搜索树。
能够快速查找数据也是二叉搜索树被用于各类数据结构的原因,但这种快速是有限制的,即不会出现退化,假如二叉搜索树退化为链表,则无法做到快速查找数据的要求,所以又出现了平衡二叉树
平衡二叉树
平衡二叉树( Balanced Binary Tree )具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。
平衡二叉树有效的限制了树高,使得二叉树不会退化为一个链表。
平衡二叉树如果同时也是一棵二叉搜索树,那么查找某个节点的效率是O(log(n))的。
很多数据结构,不能完美的做到平衡,但也能有效的控制树高,例如:红黑树。也被经常用于数据的快速查找。
满二叉数有2k-1个结点
样例代码
struct node{
char value;
int left,right;
}data[101];
int root=0,cnt;
char ch;
int buildTree(int bt){
cin>>ch;
if(ch=='.'){
bt==0;
return bt;
}else{
bt=++cnt;
data[bt].value=ch;
data[bt].left=data[bt].right=0;
data[bt].left=buildTree(bt);
data[bt].right=buildTree(bt);
}
return bt;
}
void postorder(int bt){
if(bt){
postorder(data[bt].left);
postorder(data[bt].right);
cout<<data[bt].value;
}
}
int main(){
root=0;
cnt=0;
root=buildTree(0);
postorder(root);
return 0;
}
总结:
一、二叉树的概念与性质
二叉树最多有两个儿子
二叉树的三个基本性质
完全二叉树与满二叉树的基本概念与性质
二、二叉树的储存与遍历
二叉树的独特存储与遍历方法
二叉树的前中后序遍历
二叉树遍历转化
二叉树中懒标记的应用