二叉树的建立
在讲解二叉树的建立前,请读者务必要先思考一个问题
思考问题:如何确定一个二叉树,如果只看 前序 或 中序 或 后序遍历 三种之一能够确定唯一一个二叉树的形状吗?
其中:
前序遍历结果:ADEBCF
中序遍历结果:DEACFB
后序遍历结果:EDFCBA
================================================
解:
单凭一种遍历的结果,无法确定一个二叉树,当满足以下两种情况即可满足确定。
条件1:前序和中序
条件2:中序和后序
为什么呢?证明如下:
步骤1:通过前序或后序遍历可确定根结点。(前序的第一个遍历结果,后序最后一个遍历结果)
步骤2:通过中序遍历可确定结点下的左子树和右子树部分。(通过前序和后序获得的根结点,在中序遍历中对应的该根节点位置分割左右子树)
以此类推,可确定二叉树的形状,读者不妨验证一下,加深理解。
将已知结果分为三部分,根节点和左右子树的判断,逐渐减少未知结点,重复利用前序或后序判断谁是根节点,在用中序判断谁是左子树或右子树。
二叉树形状:
================================================
ok!下面进入正题
通过输入字符来辨别是非创建对应结点,若输入’#'为空
注意:
1.创建的方式只能为先序,因为子树只有创建了根节点才能访问下层,顺序为:根节点、左子树、右子树
2.销毁的方式只能为后序,原因很简单,从低到高,不能先删除根节点,否则无法删除其对应的左右子树。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct NODE_ST{
int value;
}node_st;
typedef struct D_TREE{
node_st cur;
struct D_TREE *lchild,*rchild;
}d_tree;
void inOrder(void *Node)
{
d_tree *node = Node;
if(node == NULL)
return;
inOrder(node->lchild);
printf("%d",node->cur.value);
inOrder(node->rchild);
}
//通过#字符 创建树
d_tree *tree_Create()
{
d_tree *tmp = NULL;
char ch = 0;
printf("请输入字符:\n");
scanf(" %c",&ch);//%c前加一个空格,否则会出错,可在我的博客查看相关讲解
if(ch == '#'){
return NULL;
}
else{
tmp = (d_tree *)calloc(1,sizeof(d_tree));
if(tmp == NULL){
return NULL;
}
tmp->cur.value = atoi(&ch);
tmp->lchild = tree_Create();
tmp->rchild = tree_Create();
return tmp;
}
}
//后序销毁树
void tree_Free(d_tree *T)
{
if(T == NULL)
return;
if(T->lchild != NULL){
tree_Free(T->lchild);
T->lchild = NULL;
}
if(T->rchild != NULL){
tree_Free(T->rchild);
T->rchild = NULL;
}
if(T != NULL){
free(T);
T = NULL;
}
}
int main()
{
d_tree *node = NULL;
node = tree_Create();
inOrder(node);
printf("\n");
tree_Free(node);
return 0;
}