一、二叉树的存储结构
————顺序存储(一维数组)———

1 #define MaxSize 100 //假设二叉树最大编号为99
2 typedef char DataType; //定义二叉树节点的数据类型,假设为char型
3 typedef struct{
4 DataType data[MaxSize];
5 int biTreeNum; //二叉树的节点个数
6 }SeqBiTree;
——————二叉链表————————


1 typedef char DataType;
2 typedef struct BiNode{
3 DataType data;
4 struct BiNode * lchild,* rchild;
5 }BiNode;
二、二叉树的遍历
遍历过程
转载自https://mp.weixin.qq.com/s/HXce4H21Gbu_O9ciXzJQYw
————深度优先遍历————
1.前序遍历

2.中序遍历

3.后序遍历

————广度优先遍历————
4.层序遍历

总结:a.我们提到的四种遍历方式,其实都是在把树种的结点编程某种意义上的线性序列,这样给程序执行带来了好处。
b.前序、中序、后序遍历最根本的区别就是双亲结点的访问时机——前序是先访问双亲结点,然后左孩子,最后右孩子;中序是左孩子,双亲,右孩子;后序是左孩子、右孩子最后双亲结点。
c.树的定义就使用了递归这一方式,当然,对树的遍历也是使用递归(注意递归算法一定要有结束递归的标志)
代码实现 —— 基于二叉链表的存储结构
1.前序遍历
1 void PreOrder(BiNOde * root){
2 if(root==NULL) //递归调用的结束条件
3 return;
4 else{
5 printf("%c",root->data);//访问根节点的数据域,为char型
6 PreOrder(root->lchild); //前序递归遍历root的左子树
7 PreOrder(root->rchild);//前序递归遍历root的右子树
8 }
9 }
2.中序遍历
1 void InOrder(BiNode * root){
2 if(root==NULL){ //递归调用的结束条件
3 return;
4 }
5 else{
6 InOrder(root->lchild);//中序递归遍历root的左子树
7 printf("%c",root->data);//访问根节点的数据域,为char型
8 InOrder(root->rchild);//中序递归遍历root的右子树
9 }
10 }
3.后序遍历
1 void PostOrder(BiNode * root){
2 if(root==NULL){
3 return; //递归调用的结束条件
4 }
5 else{
6 PostOrder(root->lchild); //后序递归遍历root的左子树
7 PostOrder(root->rchild); //后序递归遍历root的右子树
8 printf("%c",root->data); //访问根节点的数据域,为char型
9 }
10 }
4.层序遍历
访问某一层的节点后,再对各个节点的左孩子和右孩子顺序访问,这样一层一层进行,先访问的节点其左右孩子也要先访问,这符合队列的操作特性。因此,在层序遍历时,设置一个队列存放已访问的节点
1 void LevelOrder(BiNode * root){
2 BiNode * q=NULL,*Q[MaxSize] //采用顺序队列
3 int front = rear =-1; //初始化顺序队列
4 if(root==NULL) //二叉树为空,算法结束
5 return;
6 Q[++rear]=root; //根指针入队
7 while(front!=rear){ //当队列非空时
8 q=Q[++front]; //出队
9 printf("%c",q->data); //访问节点,为char型
10 if(q->lchild!=NULL)
11 Q[++rear]=q->lchild;
12 if(q->rchild!=NULL)
13 Q[++rear]=q->rchild;
14 }
15 }