- 二叉树(Binary tree)是树形结构的一个重要类型。许多实际问题抽象出来的数据结构往往是二叉树形式,即使是一般的树也能简单地转换为二叉树,而且二叉树的存储结构及其算法都较为简单,因此二叉树显得特别重要。二叉树特点是每个结点最多只能有两棵子树,且有左右之分 。
- 二叉树是n个有限元素的集合,该集合或者为空、或者由一个称为根(root)的元素及两个不相交的、被分别称为左子树和右子树的二叉树组成,是有序树。当集合为空时,称该二叉树为空二叉树。在二叉树中,一个元素也称作一个结点
二叉树类型
- 满二叉树:如果一棵二叉树只有度为0的结点和度为2的结点,并且度为0的结点在同一层上,则这棵二叉树为满二叉树 。
- 完全二叉树:深度为k,有n个结点的二叉树当且仅当其每一个结点都与深度为k的满二叉树中编号从1到n的结点一一对应时,称为完全二叉树 。 完全二叉树的特点是叶子结点只可能出现在层序最大的两层上,并且某个结点的左分支下子孙的最大层序与右分支下子孙的最大层序相等或大1。
相关术语
①结点:包含一个数据元素及若干指向子树分支的信息 。
②结点的度:一个结点拥有子树的数目称为结点的度 。
③叶子结点:也称为终端结点,没有子树的结点或者度为零的结点 。
④分支结点:也称为非终端结点,度不为零的结点称为非终端结点 。
⑤树的度:树中所有结点的度的最大值。
⑥结点的层次:从根结点开始,假设根结点为第1层,根结点的子节点为第2层,依此类推,如果某一个结点位于第L层,则其子节点位于第L+1层 。
⑦树的深度:也称为树的高度,树中所有结点的层次最大值称为树的深度 。
⑧有序树:如果树中各棵子树的次序是有先后次序,则称该树为有序树 。
⑨无序树:如果树中各棵子树的次序没有先后次序,则称该树为无序树 。
⑩森林:由m(m≥0)棵互不相交的树构成一片森林。如果把一棵非空的树的根结点删除,则该树就变成了一片森林,森林中的树由原来根结点的各棵子树构成 。
二叉树性质
性质1:二叉树的第i层上至多有2i-1(i≥1)个节点 。
性质2:深度为h的二叉树中至多含有2h-1个节点 。
性质3:若在任意一棵二叉树中,有n0个叶子节点,有n2个度为2的节点,则必有n0=n2+1 。
性质4:具有n个节点的完全二叉树深为log2x+1(其中x表示不大于n的最大整数)。
性质5:若对一棵有n个节点的完全二叉树进行顺序编号(1≤i≤n),那么,对于编号为i(i≥1)的节点:
当i=1时,该节点为根,它无双亲节点 。
当i>1时,该节点的双亲节点的编号为i/2 。
若2i≤n,则有编号为2i的左节点,否则没有左节点 。
若2i+1≤n,则有编号为2i+1的右节点,否则没有右节点 。
1.二叉树表的创建
//二叉树的建立
void CreatTree(tree *T)
{
char ch;
cin>>ch;
if(ch=='#')
*T=NULL;
else
{
*T=new Csnode;
if(!T)
return;
(*T)->data=ch;
printf("请输入%c的左子树: ",ch);
CreatTree(&(*T)->lchild);
printf("请输入%c的右子树: ",ch);
CreatTree(&(*T)->rchild);
}
}
2.前中后序遍历
//前序遍历算法
void PreCreat(tree T)
{
if(T==NULL)
return ;
cout<<T->data<<" ";
PreCreat(T->lchild);
PreCreat(T->rchild);
}
//中序遍历算法
void MidCreat(tree T)
{
if(T==NULL)
return ;
MidCreat(T->lchild);
cout<<T->data<<" ";
MidCreat(T->rchild);
}
//后序遍历算法
void RearCreat(tree T)
{
if(T==NULL)
return ;
RearCreat(T->lchild);
RearCreat(T->rchild);
cout<<T->data<<" ";
}
3.测试案例
#include<iostream>
using namespace std;
//二叉树的结构定义
typedef struct csNode
{
char data;
struct csNode*lchild;
struct csNode*rchild;
} Csnode,*tree;
//二叉树的建立
void CreatTree(tree *T)
{
char ch;
cin>>ch;
if(ch=='#')
*T=NULL;
else
{
*T=new Csnode;
if(!T)
return;
(*T)->data=ch;
printf("请输入%c的左子树: ",ch);
CreatTree(&(*T)->lchild);
printf("请输入%c的右子树: ",ch);
CreatTree(&(*T)->rchild);
}
}
//前序遍历算法
void PreCreat(tree T)
{
if(T==NULL)
return ;
cout<<T->data<<" ";
PreCreat(T->lchild);
PreCreat(T->rchild);
}
//中序遍历算法
void MidCreat(tree T)
{
if(T==NULL)
return ;
MidCreat(T->lchild);
cout<<T->data<<" ";
MidCreat(T->rchild);
}
//后序遍历算法
void RearCreat(tree T)
{
if(T==NULL)
return ;
RearCreat(T->lchild);
RearCreat(T->rchild);
cout<<T->data<<" ";
}
int main()
{
printf("请输入第一个节点的数据:\n");
tree T;
CreatTree(&T);
cout<<"前序遍历:";
PreCreat(T);
cout<<"\n中序遍历:";
MidCreat(T) ;
cout<<"\n后序遍历:";
RearCreat(T) ;
}
测试结果