二叉树的遍历

345 阅读3分钟

二叉树的遍历

完全二叉树的性质

性质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); 
         }
 }