图文精讲+代码实战 清晰透彻理解数据结构c语言——二叉树的存储结构+二叉树的遍历

0二叉树也可以采用两种存储方式:顺序存储结构和链式存储结构

1. 顺序存储结构

这种存储结构适用于完全二叉树。其存储形式为:用一组连续的存储单元按照完全二叉树的每个结点编号的顺序存放结点内容。下面是一棵二叉树及其相应的存储结构。
在这里插入图片描述

2. 链式存储结构

在顺序存储结构中,利用编号表示元素的位置及元素之间孩子或双亲的关系,因此对于非完全二叉树,需要将空缺的位置用特定的符号填补,若空缺结点较多,势必造成空间利用率的下降。在这种情况下,就应该考虑使用链式存储结构。
在这里插入图片描述
在这里插入图片描述
这种存储结构的特点是寻找孩子结点容易,双亲比较困难。因此,若需要频繁地寻找双亲,可以给每个结点添加一个指向双亲结点的指针域,其结点结构如下所示。
在这里插入图片描述

二叉树的遍历:

        二叉树是一种非线性的数据结构,在对它进行操作时,总是需要逐一对每个数据元素实施操作,
        这样就存在一个操作顺序问题,由此提出了二叉树的遍历操作。
        所谓遍历二叉树就是按某种顺序访问二叉树中的每个结点一次且仅一次的过程。
        这里的访问可以是输出、比较、更新、查看元素内容等等各种操作。
  	二叉树的遍历方式分为两大类:一类按根、左子树和右子树三个部分进行访问;
  	另一类按层次访问。

1. 按根、左子树和右子树三部分进行遍历
TLR(根左右)、LTR(左根右)和LRT(左右根)根据根访问的位置不同分别被称为先序遍历、中序遍历和后序遍历。

1)先序遍历:
若二叉树为空,则结束遍历操作;否则按照顺序:
访问根结点;
先序遍历左子树;
先序遍历右子树。
2)中序遍历
若二叉树为空,则结束遍历操作;否则按照顺序:
中序遍历左子树;
访问根结点;
中序遍历右子树。
3)后序遍历
若二叉树为空,则结束遍历操作;否则按照顺序:
后序遍历左子树;
后序遍历右子树;
访问根结点。
注意:
上面三中的遍历方法中,若某个结点缺少左孩子或者右孩子的话,就将其补齐
可以用“空”补齐,补齐之后再用上面的三种方法更加思路清晰

Alt

                     都是按照先左后右的顺序进行的
先序序列: 	 ABDGCEF

中序序列:   	 空DGB空AECF
简化之后即为:    DGBAECF

后序序列:        空GD空BEFCA
简化之后即为:    GDBEFCA
由此可以看出:
1)遍历操作实际上是将非线性结构线性化的过程,其结果为线性序列,
并根据采用的遍历顺序分别称为先序序列、中序序列或后序序列;
2)遍历操作是一个递归的过程,因此,这三种遍历操作的算法可以用递归函数实现。


2. 按层次遍历二叉树
实现方法为从上层到下层,每层中从左侧到右侧依次访问每个结点。下面我们将给出一棵二叉树及其按层次顺序访问其中每个结点的遍历序列。
在这里插入图片描述
层次遍历算法设计思路:
使用一个队列
1、将根结点进队;
2、队不空时循环:从队列中出列一个结点p,访问它;
若它有左孩子结点,将左孩子结点进队;
若它有右孩子结点,将右孩子结点进队。
在这里插入图片描述

二叉树的建立:

如何把二叉树存入电脑内?
例:将下面的二叉树以二叉链表形式存入计算机内。
在这里插入图片描述
注意:标空的先序遍历序列能够唯一确定一颗二叉树

建树算法:
Status CreateBiTree( BiTree &T ){    //构造二叉树T
scanf("%c",&ch);
if(ch==' ')T=NULL; 
else{
      if(!(T=( BiTNode*)malloc(sizeof(BiTNode))))exit(overflow);
      T->data=ch;                           //生成根结点
      CreateBiTree(T->lchild);     //构造左子树
      CreateBiTree(T->rchild); //构造右子树
} return OK;
} //CreateBiTree

已知一棵二叉树的先根和中根遍历序列如下,画出此二叉树。
先根遍历序列:A B C I D E H F J G
中根遍历序列:B I C A H E J F G D

在这里插入图片描述

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

在这里插入图片描述
在这里插入图片描述

void InOrder1(BTNode *b)
{  BTNode *p;  SqStack *st; //定义一个顺序栈指针st
   InitStack(st);  //初始化栈st
   p=b;
   while (!StackEmpty(st) || p!=NULL)
   {  while (p!=NULL)  //扫描结点p的所有左下结点并进栈
      {  Push(st,p);  //结点p进栈
   p=p->lchild;  //移动到左孩子
      }
      //以下考虑栈顶结点
      if (!StackEmpty(st)) //若栈不空
      {  Pop(st,p);  //出栈结点p,访问结点p
   printf("%c ",p->data);
   p=p->rchild;  //转向处理其右子树
      }
   }
   printf("\n");
   DestroyStack(st);  //销毁栈
}
如何确定一颗唯一的二叉树?
有如下几种方法:
标空的先序序列
标空的后序序列
先序序列+中序序列
后序序列+中序序列
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱睡觉的小馨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值