目录
1.1 定义
每个节点最多有两棵子树,并且严格区分左右的树形结构
2.2 二叉树相关概念
【左子树】左子树是以当前结点的左孩子结点作为根节点的子树 【右子树】右子树是以当前结点的右孩子结点作为根节点的子树 【满二叉树】满二叉树是最后一层是叶子结点,其余结点度是2的二叉树 在不增加层次的基础上,不能在添加节点的二叉树 【完全二叉树】完全二叉树是在一棵满二叉树基础上自左向右连续增加叶子结点得到的二叉树 完全二叉树是在一棵满二叉树基础上自右向左连续删除叶子结点得到的二叉树
2.3 二叉树的五种状态
空二叉树、只有根结点、只有左子树、只有右子树、既有左子树也有右子树
2.4 二叉树的性质
性质1:在二叉树的第i层上最多有2^(i-1)个结点(i >= 1)
性质2:深度为k的二叉树最多有2^k-1个结点(k >= 1)
性质3:在任意一棵二叉树中,叶子结点的数目比度数为2的结点的数目多一
假设 n0:度数为0的所有节点的个数 n1:度数为1的所有节点的个数 n2:度数为2的所有节点的个数 总度数 = 总结点个数 - 1 总个数 = n0 + n1 + n2; 总度数 = 2*n2 + n1 最终结果:n2 = n0 - 1
性质4:如果第i个节点存在左孩子,那么其左孩子应该在树中第2*i个位置 如果第i个节点存在右孩子,那么其右孩子应该在树中第2*i+1个位置
2.5 二叉树存储
1> 顺序存储:由于在二叉树的存储中,空节点也要占一个位置,导致会浪费大量的空间,所以,存储二叉树,不常使用顺序存储 2> 链式存储:
2.6 节点结构体类型
typedef char datatype;
typedef struct Node
{
datatype data; //数据域
struct Node *left; //指向左子树的指针
struct Node *right; //指向右子树的指针
}biTree;
2.7 创建:先序创建
先创建根节点、接着创建左子树、最后创建右子树
biTree *tree_create()
{
//定义一个字符数据,存放用户输入的数据
char ch = '\0';
scanf("%c", &ch);
getchar();
if(ch == '!') //如果是‘!’说明空节点
{
return NULL;
}
//申请节点保存数据
biTree *B = (biTree *)malloc(sizeof(biTree));
if(NULL==B)
{
printf("空间申请失败\n");
return NULL;
}
B->data = ch; //将数据存入节点
B->left = tree_create(); //递归创建左子树
B->right = tree_create(); //递归创建右子树
return B; //将创建好的树,返回
}
2.7 先序遍历
也称先根遍历,先访问根节点中的内容,然后访问左子树、最后访问右子树
void pri_order(biTree *B)
{
if(NULL==B)
{
return ;
}
printf("%c\t", B->data); //先访问根节点
pri_order(B->left); //先序遍历左子树
pri_order(B->right); //先序遍历右子树
}
2.8 中序遍历
也称中根遍历,先访问左子树、然后访问根节点内容、最后访问右子树
void in_order(biTree *B)
{
if(NULL==B)
{
return ;
}
in_order(B->left); //中序遍历左子树
printf("%c\t", B->data); //访问根节点
in_order(B->right); //中序遍历右子树
}
2.9 后续遍历
也称后根遍历,先访问左子树、然后访问右子树、最后访问根节点内容
void post_order(biTree *B)
{
if(NULL==B)
{
return ;
}
post_order(B->left); //后序遍历左子树
post_order(B->right); //后序遍历右子树
printf("%c\t", B->data); //访问根节点
}
代码实现↓
bitree.h
#ifndef __BITREE_H__
#define __BITREE_H__
typedef int datatype;
typedef struct Node
{
datatype data;
struct Node *L;
struct Node *R;
}bitree;
//创建
bitree *create();
//先序遍历
void pri_order(bitree *B);
//中序遍历
void in_order(bitree *B);
//后序遍历
void post_order(bitree *B);
#endif
bitree.c
#include<stdlib.h>
#include"bitree.h"
#include<stdio.h>
//创建
bitree *create()
{
char val=0;
printf("请输入:");
scanf("%c",&val);
getchar(); //吸收回车
if (val=='#')
{
return NULL;
}
bitree *p=(bitree *)malloc(sizeof(bitree));
if (NULL==p)
{
printf("申请失败\n");
return NULL;
}
p->data=val;
p->L=create();//建立左子树
p->R=create();//建立右子树
return p;
}
//先序遍历
void pri_order(bitree *B)
{
if (NULL==B)
{
return ;
}
//访问根节点
printf("%c\t",B->data);
//先序遍历左子树
pri_order(B->L);
pri_order(B->R);
}
//中序遍历
void in_order(bitree *B)
{
if (NULL==B)
{
return ;
}
//先遍历左子树
pri_order(B->L);
//访问根节点
printf("%c\t",B->data);
//遍历右子树
pri_order(B->R);
}
//后序遍历
void post_order(bitree *B)
{
if (NULL==B)
{
return ;
}
//先遍历左子树
pri_order(B->L);
//遍历右子树
pri_order(B->R);
//访问根节点
printf("%c\t",B->data);
}
main.c
#include<stdlib.h>
#include"bitree.h"
#include<stdio.h>
int main(int argc, const char *argv[])
{
bitree *B=create();
if (NULL==B)
{
return -1;
}
printf("创建成功\n");
//先序遍历函数
printf("先序遍历\n");
pri_order(B);
printf("\n");
//中序遍历函数
printf("中序遍历\n");
pri_order(B);
printf("\n");
//后序遍历函数
printf("后序遍历\n");
pri_order(B);
printf("\n");
return 0;
}