二叉树的遍历
完全二叉树的性质
性质1:在二叉树的第n层至多有2^(n-1)个结点( i>=1)。
性质2:深度为k的二叉树至多有2^k-1个结点(k>=1)。
性质3:对任何一棵二叉树T,如果其终端结点数位n0,度为2的结点数位n2,则n0 = n2+1。 性质4:具有n个结点的完全二叉树的深度为[以2为底n的对数]+1。
性质5:如果对一棵有n个结点的完全二叉树(深度为[以2为底n的对数]+1)的结点按层序编号,每层从左到右,对任一结点i(1<= i <=n) 有:
如果i=1,则结点i是二叉树的根,无双亲;如果i > 1,则其双亲是结点[i/2]。 如果2i > n,则结点i无左孩子(结点i为叶子结点);否则其左孩子是2i。 如果2i+1>n,则结点i无右孩子;否则其右孩子是结点2i+1。
二叉树的存储结构
顺序
用地址连续的存储单元,按照一定的规律存储二叉树的结点
- 对于完全二叉树:从根起按层存储,从上到下从左到右,将二叉树中编号为i的结点元素存储在定义的一维数组下标为i-1的分量
- 对于一般二叉树:将每个结点与完全二叉树上的结点相对照,以“0”表示不存在此结点,存储在一维数组中,
代码
//二叉树的顺序存储表示
#define MAXTSIZE 100 //二叉树的最大结点
typedef TElemType SqBiTree[MAXTSIZE]; //0号单元存储根结点
SqBiTree bt;
链式
用链指示元素间的逻辑关系
// 二叉链表
struct BinaryTreeNode
{
struct BinTreeNode* _pLeft; // 指向当前节点左孩子
struct BinTreeNode* _pRight; // 指向当前节点右孩子
TElemType data; // 当前节点值域
}
// 三叉链表
struct BinaryTreeNode
{
struct BinTreeNode* _pParent; // 指向当前节点的双亲
struct BinTreeNode* _pLeft; // 指向当前节点左孩子
struct BinTreeNode* _pRight; // 指向当前节点右孩子
TElemType data; // 当前节点值域
};
遍历二叉树
定义
二叉树的遍历是指从根结点出发,按照某种次序访问二叉树中的所有结点,使得每个结点被访问一次且仅被访问一次
说明
- 访问:对结点做各种处理,包括输出结点的信息、对结点进行运算和修改
- 遍历的实质:对二叉树线性化
- 遍历的结果:将非线性结构的树中结点排成一个线性序列
- 规律:找一种规律,将非线性结构的树中结点排成一个线性序列 持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第10天
算法
链表--递归算法
//前序遍历:
void Traverse(BiTree &T)
{
if(T){
printf("%d ",T->data);
Traverse(T->Lchild);
Traverse(T->Rchild);
}
}
//中序遍历:
void midTraverse(BiTree &T)
{
if(T){
midTraverse(T->Lchild);
printf("%d ",T->data);
midTraverse(T->Rchild);
}
}
//后序遍历:
void lasTraverse(BiTree T)
{
if(T){
lasTraverse(T->Lchild);
lasTraverse(T->Rchild);
printf("%d ",T->data);
}
}