二叉树的存储结构及遍历算法

二叉树的顺序存储:

用一块连续的空间存储二叉树的节点,存储的顺序按从上到下,从左至右的顺序。

顺序存储一般适合存储 : 满二叉树和完全二叉树。 

对于一般二叉树,如果用顺序存储,且需要反映出一定的逻辑关系(即能用数组元素下标值反映元素在二叉树中的位置),此时可能会需要定义一些虚结点。即存储时,存储虚结点的空间即存储0值。(弊端是浪费了太多空间)所以,对于一般二叉树不适合用顺序存储结构。


二叉树的链式存储: 用链表来表示一棵二叉树


1二叉链表存储结构: 链表每个结点包含两个指针域(分别指向 左孩子结点和右孩子结点)以及数据域。 ,当左孩子或右孩子不存在时将对应的指针域设为NULL。

2三叉链表存储结构:链表每个结点包含三个指针域(分别指向左孩子结点和右孩子结点以及双亲结点)以及数据域。


二叉树是最常用二叉树存储结构(对于一般的二叉树,二叉链表存储结构甚至比顺序存储结构还要节省存储空间)。

含有n个结点的二叉链表中含有n+1个空指针域。  设深度为k , 则最后一层的结点数为 2^(k-1)  , 总结点数为 2^k-1 ,由于每个结点含有两个指针域,故有2*2^(k-1)+1个空指针域,即 为 n+1 此为特殊情况。

正常推导为:由于n个结点有2n个指针域,但是只需要存储n-1个结点的信息,所以有n+1个指针域会空闲。


二叉树的静态链表存储结构,和静态链表一样是为了那些不支持指针类型的程序设计语言。


二叉树的正则化扩展:当结点存在一个子结点,但无另外的一个左或右孩子结点时,补充一个虚结点,使原二叉树的结点都称为分支结点,这种补充称为二叉树的正则化扩展。


二叉树的遍历算法:递归过程。

先序遍历: 1、先访问根结点 ;2、先序遍历根结点的左子树;3、先序遍历根结点的右子树。

中序遍历: 1、中序遍历根结点的左子树;2、访问根结点;3、中序遍历根结点的右子树。

后序遍历: 1、后序遍历根结点的左子树;2、后序遍历根结点的右子树;3、访问根结点。

/

二叉树的非递归遍历算法:

先序遍历 : 实质上就是进栈出栈的过程。

 void Preorder(BiTree BT , *visit( ElemType))

{

if (BT) 

{InitStack(S) ; //初始化一个栈

push(S,BT) ;

while(!StackEmpty(S))

{  pop(S,p) ; visit(p->data) ;  //访问根结点     if(p->rchild)  push(S,p);  if(p->lchild) push(S,p) ;} //栈是先进后出,所以先进栈右孩子结点。

}

}

///

中序遍历:同理

void Inorder(BiTree BT,*visit(ElemType))

{

if(BT)

{p = BT; 

initStack(S) ;

while( p || !Stackempty(S))

{   if(p)  { push(S,p) ; p=p->lchild ;  //深入到左子树的叶子结点。}

else  {  pop(S,p); visit(p->data); p=p->rchild ; //进入(左子树往下的分支)右子树}

}

}

}

///

后序遍历:

Postorder(BiTree BT ,*visit(ElemType))

{

BitTree S[n] ;   //初始化一个静态栈(用数组表示栈,top为栈顶索引)

int Tag[n] ; top =0  ; 

p = BT ;

while( p || top )

{

while( p ) 

{  S[top] = p ;  Tag[top] =0 ; top++ ; }

while( top && Tag[top]==1)

{  p = S[top] ; top-- ; visit(p->data) ;}

if(top)

{ Tag[top] = 1 ; p=S[top]->rchild ; }  //因为已经到了左子树的叶子结点,此时p指向叶子结点的左孩子结点,且其指针为NULL,故此时应该访问栈里根结点的右子树结点。

}

}

///

//

层次遍历:从上到下,每层从左至右访问结点。 先遇到的先访问,其符合队列的特性。

算法描述:

Levelorder(BiTree BT ,*visit(ElemType))

{

InitQueue(Q) ;

EnQueue(Q,BT) ;

while(!QueueEmpty(Q))

{

DeQueue(Q,p) ;

visit(p->data) ;

if (p->lchild)   EnQueue(Q,p->lchild) ;

if(p->rchild)   EnQueue(Q,p->rchild) ;

}

}




  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值