目录
一、二叉树的基本概念
深度:对于任意结点ni,ni的深度为从根到ni的唯一路径的长,根的深度为0。
高度:ni的高是从ni到一片树叶的最长路径的长。所有树叶的高为0,树的高=根的高。
内部路径长:一棵树的所有结点的深度和。
性质1:二叉树第i层上的结点数目最多为2i-1(i>=1)
性质2:深度为k的二叉树至多有2k-1个结点(k>=1)
性质3:包含n个结点的二叉树的高度至少为(log2n)+1(向下取整)
性质4:在任意一棵二叉树中,若终端结点的个数为n0,度为2的结点数为n2,则n0=n2+1
性质1:二叉树第i层上的结点数目最多为 2{i-1} (i≥1)
证明:下面用"数学归纳法"进行证明。
(01) 当i=1时,第i层的节点数目为2{i-1}=2{0}=1。因为第1层上只有一个根结点,所以命题成立。
(02) 假设当i>1,第i层的节点数目为2{i-1}。这个是根据(01)推断出来的!
下面根据这个假设,推断出"第(i+1)层的节点数目为2{i}"即可。
由于二叉树的每个结点至多有两个孩子,故"第(i+1)层上的结点数目" 最多是 "第i层的结点数目的2倍"。即,第(i+1)层上的结点数目最大值=2×2{i-1}=2{i}。
故假设成立,原命题得证!
性质2:深度为k的二叉树至多有2{k}-1个结点(k≥1)
证明:在具有相同深度的二叉树中,当每一层都含有最大结点数时,其树中结点数最多。利用"性质1"可知,深度为k的二叉树的结点数至多为:
20+21+…+2k-1=2k-1
故原命题得证!
性质3:包含n个结点的二叉树的高度至少为log2 (n+1)
证明:根据"性质2"可知,高度为h的二叉树最多有2{h}–1个结点。反之,对于包含n个节点的二叉树的高度至少为log2(n+1)。
性质4:在任意一棵二叉树中,若终端结点的个数为n0,度为2的结点数为n2,则n0=n2+1
证明:因为二叉树中所有结点的度数均不大于2,所以结点总数(记为n)="0度结点数(n0)" + "1度结点数(n1)" + "2度结点数(n2)"。由此,得到等式一。
(等式一) n=n0+n1+n2
另一方面,0度结点没有孩子,1度结点有一个孩子,2度结点有两个孩子,故二叉树中孩子结点总数是:n1+2n2。此外,只有根不是任何结点的孩子。故二叉树中的结点总数又可表示为等式二。
(等式二) n=n1+2n2+1
由(等式一)和(等式二)计算得到:n0=n2+1。原命题得证!
二、二叉树的存储结构
三、二叉树的建立与遍历
二叉树的深度优先遍历(dfs):先序遍历、中序遍历、后序遍历
二叉树的宽度优先遍历(bfs):层序遍历
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
#include<queue>
#include<iostream>
using namespace std;
typedef struct node{
char val;
struct node* left;
struct node* right;
}*BT,BTnode;
void create(BT &T) //二叉树的先序建立
{
char c;
cin>>c;
if(c=='#')T=NULL;
else{
T=new BTnode();
T->val=c;
create(T->left);
create(T->right);
}
}
void post(BT T)//二叉树的后序遍历
{
if(T!=NULL){
post(T->left);
post(T->right);
cout<<T->val;
}
}
void level(BT T)//层序遍历
{
if(T==NULL)return;
queue<BT>q;
q.push(T);
while(!q.empty()){
BT c=q.front();
q.pop();
cout<<c->val;
if(c->left!=NULL){
q.push(c->left);
}
if(c->right!=NULL){
q.push(c->right);
}
}
}
int treeheight(BT T)
{
if(T==NULL)return 0;
else{
int left=treeheight(T->left);
int right=treeheight(T->right);
return max(left,right)+1;
}
}
int main()
{
BT T;
//1.二叉树的建立(先序)
create(T);
cout<<"后序遍历:";
//2.二叉树的遍历(后序)
post(T);
cout<<endl;
//二叉树的遍历(层序bfs)
cout<<"层序遍历:";
level(T);
cout<<endl;
//二叉树的高度
cout<<treeheight(T)<<endl;
return 0;
}