二叉树
二叉树是有限的节点集合——递归定义
这个集合或者是空或者由一个根节点和两棵互不相交的称为左子树和右子树的二叉树组成
二叉树的性质
(1)非空二叉树上的叶节点树等于双分支节点加1
(2)非空二叉树上的第i层最多有2^(i-1)个节点
(3)高度为h的二叉树至多有2^h-1个节点
高度为h的m次树至多有m^h-1/m-1个节点
满二叉树
在一棵二叉树中,如果所有分支节点都有左孩子节点和右孩子节点,并且叶节点都集中在二叉树的最下一层,这样的二叉树被称为满二叉树
特点
(1)叶子节点都在最下一层
(2)只有度为0或者2的节点
对满二叉树节点的连续编号:树根为1,按照层数从小到大、同一层从左到右的次序进行编号
完全二叉树
若二叉树最多只有最下两层的节点的度可以小于2,并且最下面一层的叶节点都依次排列在该层最左边的位置上,则这样的二叉树被称为完全二叉树。
编号同满二叉树
森林、树转化为二叉树
(1)在所有相邻兄弟节点(森林中每棵树的根节点可看成兄弟节点)之间加以水平连线
(2)队每个非叶节点k,除了其最左边的孩子节点外,删去k与其它孩子节点的连线
(3)所有水平线段以左边节点为轴心顺时针旋转45度(兄弟作为右孩子)
二叉树还原为森林、树
(1)对于一棵任意的二叉树中的任一节点k1,沿着k1的右子树方向搜索所有右孩子节点,得节点序列k2.k3.k3…km,其中ki+1为ki的右孩子节点,km没有右孩子节点
(2)删去k1,k2…km之间的连线
(3)若k1具有双亲节点k,则连接k与ki(2≤i≤m)
(4)将图像规整化
二叉树的存储结构
顺序存储结构
按编号次序存储节点
对树的每个节点进行编号
其编号从小到大的顺序就是节点在连续存储单元的先后次序
(1)编号为i的节点的左孩子节点为2i,右孩子节点为2i+1
(2)除树根节点外,若一个节点的编号为i,它的双亲节点为i/2(向下取整)
对于一般的二叉树
先用空节点补全称为完全二叉树
再对节点编号
二叉树的链式存储结构
//二叉树的链式存储结构
typedef struct node
{
ElemType data;
struct node *lchild,*rchild;
} BTNode;
data表示值域,用于存储对应的数据元素
lchild和rchild分别表示左指针域和右指针域,用于存储左孩子节点和右孩子节点
创建二叉树
算法描述
//创建二叉树
void CreateBTNode(BTNode *&b,char *str) //b是根节点 str是字符串
{
BTNode *St[MaxSize],*p=NULL; //St[]是栈 用于中转 p是创建节点的空间 temp
int top=-1,k,j=0; //top是栈的指针 k是用于压栈的case j是用于计数
char ch; //用于保存str中的字符
b=NULL;
ch=str[j];
while(ch!='\0')
{
switch(ch)
{
case '(':
top++; //栈指针向上移
St[top]=p; //节点入栈 为双亲节点
k=1; //下一个节点为左孩子节点 压栈的case 为左孩子的case
break;
case ',':
top--; //下一个节点为右孩子 指针向下移
break;
case ')':
k=2; //下一个节点为右孩子 压栈的case 为右孩子的case
break;
default: //为字符
p=(BTNode*)malloc(sizeof(BTNode)); //为字符创建节点
p->data=ch;
p->lchild=p->rchild=NULL; //左孩子右孩子指向NULL
if(b==NULL) //若没有根 则p成为根
b=p;
else
{
switch(k)
{
case 1:
St[top]->lchild=p;
break;
case 2:
St[top]->rchild=p;
break;
}
}
j++; //下一个字符
ch=str[j];
}
}
查找节点
找到值为x的节点,并返回节点指针,否则返回NULL
用递归算法,采用“根-左子树-右子树”的顺序,查找值为x的节点
//查找节点
BTNode *FindNode(BTNode *b,ElemType x)
{
BTNode *p;
if(b==NULL)
return NULL;
else if(b->data==x)
return b;
else
{
p=FindNode(b->lchild,x);
if(p!=NULL)
return p;
else
return FindNode(b->rchild,x);
}
}
求二叉树高度
二叉树高度的递归模型
F(b)= 0 , b=NULL
MAX{f(b->lchild),f(b->rchild)}+1 其他情况
//求高度
int BTNodeDepth(BTNode *b)
{
int lchilddep,rchilddep;
if(b==NULL)
return(0); //树为空
else
{
lchilddep=BTNodeDepth(b->lchild);
rchilddep=BTNodeDepth(b->rchild);
return (lchilddep>rchilddep)?(lchilddep+1):(rchilddep+1);
}
}
输出二叉树
对于非空二叉树b
(1)先输出其元素值
(2)当存在左孩子或右孩子节点时
输出“(”
递归处理左子树
输出“,”
递归处理右子树
输出“)”
//输出二叉树
void DispBTNode(BTNode *b)
{
if(b!=NULL)
{
cout<data;
if(b->lchild!=NULL||b->rchild!=NULL)
{
cout<<”(“;
DispBTNode(b->lchild);
if(b->rchild!=NULL)
cout<<”,”;
DispBTNode(b->rchild);
cout<<”)”;
}
}
}