【数据结构】二叉树的存储结构及先/中/后序递归遍历算法(C语言)

1. 树与二叉树

1.1 树的基本概念

是 n(n>=0)个结点的有限集合 T。当 n = 0 时,称为空树;当 n>0 时,该集合满足:
① 其中必有一个称为(root)的特定结点,它没有直接前驱,但有零个或多个直接后驱。
② 其余 n-1 个结点可以划分成 m(m>=0)个互不相交的有限集 T1,T2,T3,…,Tn,其中Ti又是一棵树,称为根的子树。每棵子树的根结点有且仅有一个直接前驱,但有零个或多个直接后继。
树的表示方法(1)结点:包括一个数据元素及若干指向其他结点的分支信息。
(2)结点的度:一个结点的子树个数称为此结点的度。
(3)叶结点:度为 0 的结点,即无后继的结点,也称为终端结点
(4)分支结点:度不为 0 的结点,也称为非终端结点
(5)结点的层次:从根结点开始定义,根结点的层次为1,根的直接后继层次为2,以此类推。
(6)结点的层序编号:将树中的结点按从上层到下层、同层从左到右的次序排成一个线性序列,依次给它们编以连续的自然数。
(7)树的度:树中所有结点的度的最大值。
(8)树的高度(深度):树中所有结点的层次的最大值。
(9)有序树:在树 T 中,如果各子树 Ti 之间是有先后次序的,则称为有序树。
(10)森林:m(m>=0)棵互不相交的树的集合。将一颗非空树的根结点删去,树就变成一个森林;反之给森林增加一个统一的根结点,森林就变成一棵树。
(11)同构:对两棵树,通过对结点适当地重命名,就可以使两棵树完全相等(结点对应相等,对应结点的相关关系也相等),则称这两棵树同构。
(12)孩子结点:一个结点的直接后继称为该结点的孩子结点。如B、C是A的孩子。
(13)双亲结点:一个结点的直接前驱称为该结点的双亲结点。如A是B、C的双亲。
(14)兄弟结点:同一双亲结点的孩子结点之间互称兄弟结点。例如H、I、G互为兄弟。
(15)堂兄弟:父亲是兄弟关系或堂兄关系的结点称为堂兄弟结点。如结点E、G、H互为堂兄弟。
(16)祖先结点:一个结点的祖先结点是指从根结点到该结点的路径上的所有结点。如结点K的祖先是A、B、E。
(17)子孙结点:一个结点的直接后继和间接后继称为该结点的子孙结点。如结点D的子孙是H、I、J、M。
(18)前辈:层号比该结点小的结点都称为该结点的前辈。如结点A、B、C、D都可称为结点E的前辈。
(19)后辈:层号比该结点大的结点都称为该结点的后辈。如结点K、L、M都可称为结点E的后辈。

1.2 二叉树的基本概念

把满足以下两个条件的树结构称为二叉树
① 每个结点的度都不大于2。
② 每个结点的孩子结点次序不能任意颠倒。
因此,一个二叉树的每个结点只能含有0、1或2个孩子,而且每个孩子有左右之分,位于左边的孩子称为左孩子,位于右边的孩子称为右孩子。
满二叉树:深度为 k 且有(2^k) -1个结点的二叉树。在满二叉树中,每层结点都是满的,即每层结点都具有最大的结点数。
完全二叉树:深度为k,结点数为n的二叉树,如果其结点1-n的位置序号分别与等高的满二叉树的结点1-n的位置序号一一对应,则为完全二叉树。
二叉树的性质
性质一:在二叉树的第 i 层上至多有2^(i-1)个结点(i>=1)。
性质二:深度为 k 的二叉树至多有(2^k) -1个结点(k>=1)。
性质三:对任意一棵二叉树T,若终端结点数为n0,而其度数为2的结点数为n2,则n0=n2+1。
性质四:具有n个结点的完全二叉树的深度为⌊log2 (n)⌋+1。
性质五:对于具有n个结点的完全二叉树,如果按照从上到下和从左到右的顺序对二叉树中的所有结点从1开始顺序编号,则对于任意的序号为 i 的结点有:
① 如 i =1,则序号为 i 的结点是根结点,无双亲结点;如 i >1,则序号为 i 的结点的双亲结点序号为⌊i / 2⌋。
② 如 2i>n,则序号为 i 的结点无左孩子;如 2i<=n,则序号为 i 的结点的左孩子结点的序号为2i。
③ 如 2i+1>n,则序号为 i 的结点无右孩子;如 2i+1<=n,则序号为 i 的结点的右孩子结点的序号为2i+1。

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

2.1 二叉树的存储结构

对于任意二叉树来说,每个结点只有一个双亲结点(根除外),最多有两个孩子,因此每个结点至少包含三个域:数据域、左孩子域和右孩子域。
二叉树结点结构其中,LChild域指向该节点的左孩子,Data域记录该节点的信息,RChild域指向该结点的右孩子。此结点结构形成的二叉树称为二叉链表。
二叉链表
代码

/*二叉树的链式存储结构*/
typedef char DataType;
typedef struct Node {
   
	DataType data;
	struct Node* LChild;
	struct Node* RChild;
}BiTNode, * BiTree;

2.2 二叉树的先序、中序、后序遍历

先序遍历(DLR)操作过程:
① 访问根结点;
② 按先序遍历左子树;
③ 按先序遍历右子树。
中序遍历(LDR)操作过程:
① 按中序遍历左子树;
② 访问根结点;
③ 按中序遍历右子树。
后序遍历(LRD)操作过程:
① 按后序遍历左子树;
② 按后序遍历右子树;
③ 访问根结点。
二叉树的遍历二叉树遍历代码

/*先序遍历二叉树(递归)*/
void PreOrder(BiTree bt) {
   
	if (bt != NULL) {
   
		printf("%c ", bt->data);		//输出结点值
		PreOrder(bt->LChild);			//先序遍历左子树
		PreOrder(bt->RChild);			//先序遍历右子树
	}
}

/*中序遍历二叉树(递归)*/
void InOrder(BiTree bt) {
   
	if (bt != NULL) {
   
		InOrder
  • 4
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值