#include <stdio.h>
#include <stdlib.h>
//定义一个树节点的结构
struct treeNode{
char data;
struct treeNode *lchild, *rchlid;
};
//创建树的各个节点
int create_tree(struct treeNode**);
//遍历二叉树
int show_tree(struct treeNode*);
int main(){
//定义一个指向树节点的指针
struct treeNode *root;
//调用创建函数时,传递的是root的地址(函数接收的时候只能用指针的指针)
//这样做可以直接对节点进行操作,而不用靠返回值来返回一个建好了的树的根节点
create_tree(&root);
//遍历树的各个节点,传递的是指向树的根节点的指针,因为不用对节点做什么操作,所以传递这个指针就可以了
//递归的时候也比较方便,因为root其实和root->lchild 是一样的(一个级别的),都是指向节点的指针
show_tree(root);
return 0;
}
//创建树的各个节点
//用二级指针**t来接收主函数传过来的 &root
int create_tree(struct treeNode**t){
//给节点负值用的char型变量
char element;
//提示输入节点值
printf("enter the data(char):");
//接受之前清一下缓存,以防下一次递归的时候把上一次输入后的“回车”读进来
fflush(stdin);
//接收
scanf("%c",&element);
//这一句很重要,这是递归能够结束的条件,把一个节点的左右孩子都负值成#,则递归结束
//建立树的时候心里得有数,算着点建立到什么节点了
if (element == '#'){
*t = NULL;
}
else{
//给*t分配空间
(*t) = (struct treeNode*)malloc(sizeof(struct treeNode));
//下面三句的顺序决定了是 前/中/后 序建立树
//这里是前序建立
(*t)->data = element;
create_tree(&(*t)->lchild);
create_tree(&(*t)->rchlid);
}
//返回
//**t将被销毁,但是它的使命已经完成了,建立树的过程中,它一直在间接引用着指向数节点的指针
return 0;
}
//遍历二叉树
//遍历不用对树节点进行操作,所以直接传个指针过来就可以了,而且比较方便递归,因为递归的参数左孩子有孩子,也都是指针
int show_tree(struct treeNode* t){
//这句很重要,这也是递归结束的条件,当节点为空时直接返回,不继续做递归了
//如果没有这句,将会是无限递归下去
if (t == NULL)
return 0;
//这三句的顺序同样决定了是前/中/后序遍历树
//这里是中序遍历树
show_tree(t->lchild);
printf("%c", t->data);
show_tree(t->rchlid);
//返回,*t将被销毁,无所谓,反正我们只是用t来挨个指了一遍树上的每个节点,没有别的用处
return 0;
}