这是我参与11月更文挑战的第4天,活动详情查看:2021最后一次更文挑战
1.定义
- 树:是n个有限数据元素的集合(n>=0)
其树相关的术语:
结点:图中有6个结点
结点的度: 一个结点的孩子个数为结点的度 如B的度为2
叶子结点: 度为0的结点 也可以说没有孩子的结点 如图中D,E,F
分支结点: 度不为0的结点 如图中 A,B,C
兄弟结点: 具有相同父亲的结点 如D,E为兄弟结点
树的层数: 树的根结点为第一层 其余结点的层为双亲结点层数加1 其中树的层数3
树的深度: 树中结点的最大层数为数的深度
图a
2.二叉树
- 二叉树:是每个结点最多有两颗子树(结点的度小于等于2)且二叉树有左右之分 不能任意颠倒次序
- 满二叉树: 深度为k且有 2k-1 个结点的二叉树 其每一层上的结点数都是最大结点数
- 完全二叉树: 对满二叉树的结点进行连续编号,约定编号从根结点起,自上而下,自左至右。深度为k的,有n个结点的二叉树,当且仅当其每一个结点都与深度为k的满二叉树中编号从1至n的结点一一对应,称之为完全二叉树
3.二叉树的性质:
1.在二叉树的第i层最多有2^(i-1)
2.深度为k的二叉树最多有2^k - 1 个结点
3.对任何一棵二叉树T,如果其度为0的结点个数为n0,度为2的结点数为n2,则 n0 = n2 + 1
4.具有n个结点的完全二叉树的深度为 ⌊log2n⌋+1
- 对一棵有n个结点的完全二叉树按层序编号则对任一结点i(1<=i<=n),有:
(1)如果i=1,则结点i是二叉树的根,无双亲;如果i>1,则其双亲为⌊i/2⌋
(2)如果2i>n,则结点i无左孩子(结点i为叶子结点);2i<=n 则i结点的左孩子结点序号是2i
(3)如果2i+1>n,则结点i无右孩子;2i+1<=n否则其右孩是2i+1
4. 存储结构
- 顺序存储结构 用一组连续的存储单元存放二叉树的结点
如图a 我们最后存放就是
#define MaxSize 100
typedef struct {
char tree[MaxSize];
int treeNum;
}BiTreec
- 链式存储 用链表来表示一棵二叉树 根据二叉树的特点,我们可知一个结点应该包含三个部分 一个指向左孩子的指针 一个指向有孩子的指针和一个数据域
typedef struct node{
char data;
struct node *lchild,*rchild;
}BiTree;
4.二叉树的遍历(递归实现)
- 前提
typedef struct Node{
char Data;
struct Node *left,*right;
}BiTNode;*BiTree
//创建二叉树 T是一个二级指针
void createBiTree(BiTree *T){
int data;
scanf("%c",&data);
if(data=="*"){
T=NULL;
}else{
*T=(BiTree)malloc(sizeof(BiTNode));
(*T)->data = data;
createBiTree((*T)->lchild);
createBiTree((*T)->rchild);
}
}
- 前序遍历
void preOrder(BiTree T){
if(T==NULL) retrun ;
printf("%c",T->data);
preOrder(T->lchild);
preOrder(T->rchild)
}
- 中序遍历
void midOrder(BiTree T){
if(T==NULL) retrun ;
midOrder(T->lchild);
printf("%c",T->data);
midOrder(T->rchild)
}
- 后序遍历
void rearOrder(BiTree T){
if(T==NULL) retrun ;
rearOrder(T->lchild);
rearOrder(T->rchild)
printf("%c",T->data);
}