目录
树是n个结点的有限集(n>=0)
若n=0,则称为空树
若n>0,则满足如下条件:
- 有且仅有一个特定的结点,称为根
- 其余结点可分为m个互不相交的有限集T1,T2,T3...Tm(m>=0),其中每个集合本身又是一棵树,称为根的子树
根结点 | 非空树中没有前驱结点的结点,例如A |
结点的度 | 结点拥有的子树的个数,例如:A的度为3,B的度为2,H的度为0 |
叶子/终端结点 | 结点的度等于0,例如:K,L,H |
分支/非终端结点 | 结点的度不等于0,例如:D |
树的度 | 树内个结点的最大值,例如图示,树的度为3 |
树的深度 | 把上图的结点每一行记为一层,树的深度就是层数的最大值,在本例中就是4 |
二叉树是n(n>=0)个结点的有限集,不是树的特殊情况,两者是两个概念
如果二叉树有三个结点,则用二叉树和普通树分别表示为:
- i 层中最多有
" role="presentation"> 个结点,至少有 1 个结点。 2 i − 1 - 深度为K的二叉树至多有
2 k − 1 " role="presentation"> 个结点,至少有 k 个结点。- 对于一棵二叉树,叶子树为
" role="presentation"> ,度为2 的结点数为 n 0 " role="presentation"> ,那么 n 2 n 0 = n 2 + 1 " role="presentation">
性质:
具有n个结点的完全二叉树的深度为[
性质:
如果对一棵有n个结点的完全二叉树,则对任一结点i(1<=i<=n)有:
缺点:会出现最坏的情况,深度为k的且只有k个结点的单只树需要长度为
头文件
- #include "Queue.h"
- #include "Stack.h"
- #include "define.h"
- #ifndef __BINARYTREE_H
- #define __BINARYTREE_H
- typedef char BitreeElemType;
- typedef struct __BiNode
- {
- BitreeElemType data;
- __BiNode *lchild, *rchild;
- }BiNode, *BiTree;
-
- void InOrder(BiTree T);
- void PreOrder(BiTree T);
- void PostOrder(BiTree T);
- void LevelOrer(BiTree T);
- void Copy(BiTree *Tnew, const BiTree T);
- void Destroy(BiTree *root);
- #endif
二叉链表
- typedef char ElemType;
- typedef struct BiNode
- {
- ElemType data;
- struct BiNode *lchild, *rchild;//左孩子,右孩子指针
- } BiNode, *BiTree;
先序遍历 | 中序遍历 | 后序遍历 |
若二叉树为空,则空操作 | ||
访问根节点; 先序遍历左子树; 先序遍历右子树; | 中序遍历左子树; 访问根节点; 中序遍历右子树; | 后序遍历左子树; 后序遍历右子树; 访问根节点; |
遍历二叉表的三种方法
- void InOrder(BiTree T)//中序
- {
- if (!T)
- return;
- InOrder(T->lchild);
- printf("%c ", T->data);
- InOrder(T->rchild);
- }
- void PreOrder(BiTree T) //先序
- {
- if (!T)
- return;
- printf("%c ", T->data);
- PreOrder(T->lchild);
- PreOrder(T->rchild);
- }
- void PostOrder(BiTree T) //后序
- {
- if (!T)
- return;
- PostOrder(T->lchild);
- PostOrder(T->rchild);
- printf("%c ", T->data);
- }
使用队列(易理解):
- void LevelOrer(BiTree T)
- {
- BiTree temp = NULL;
- SqQueue Q;
- InitQueue(&Q);
- if (T) // 先入队根
- EntryQ(&Q, T);
- while (!IsEmpty(&Q))
- {
- OutQ(&Q, &temp); // temp暂存弹出值
- printf("%c", temp->data); //输出
- if (temp->lchild) //在入队temp的左孩子和右孩子
- EntryQ(&Q, temp->lchild);
- if (temp->rchild)
- EntryQ(&Q, temp->rchild);
- }
- }
- void Creat_BiTree_Pre(BiTree *T)
- {
- //根据输出字符识别虚空节点,'#' 代表虚空节点
- char e;
- scanf(" %c", &e); //输入字符
- if ( e== '#')
- *T = NULL; //设置虚空节点
- else
- {
- *T = (BiTree)malloc(sizeof(BiNode));
- (*T)->data = e; //生成根结点
- Creat_BiTree_Pre(&(*T)->lchild);//构造左子树
- Creat_BiTree_Pre(&(*T)->rchild);//构造右子树
- }
- }
如果,是空树,递归结束;
否则,复制新结点空间,复制根结点:
- void Copy(BiTree *Tnew, const BiTree T)
- {
- if (!T)//如果是空树则返回
- {
- *Tnew = NULL;
- return;
- }
- else
- {
- *Tnew = (BiTree)malloc(sizeof(BiNode));
- (*Tnew)->data = T->data;
- Copy(&(*Tnew)->lchild, T->lchild);
- Copy(&(*Tnew)->rchild, T->rchild);
- }
- }
- //递归的方式
- void Destroy(BiTree *root)
- {
- //销毁操作必须按照后续遍历的顺序
- if (!(*root))
- return;
- else
- {
- Destroy(&(*root)->lchild);
- Destroy(&(*root)->rchild);
- free(*root);
- *root = NULL;
- }
- }
👍🏻点赞,你的认可是我创作的动力!
⭐收藏,你的青睐是我努力的方向!
✏️评论,你的意见是我进步的财富!