/**********************************************************************************************************
树(二叉树)的抽象数据类型:
InitTree(T); 构造空树
CreateTree(T);初始化
DestroyTree(T); 销毁树T
ClearTree(T); 清空树
TreeEmpty(T); 判空
TreeDepth(T); 求深度
Root(T); 获取根节点
value(T,cur_e); cur_e是树中节点,返回节点数据
Assign(T,cur_e,value); 给cur_e 赋值value
Parent(T,cur_e);根节点,返回空,否则返回双亲
LeftChild(T,cur_e); 非叶节点,返回其最左孩子(长子)否则为空
RightSibling(T,cur_e); 有右兄弟则返回右兄弟,否则为空
InsertChild(T,p,i,c);p指向某个节点,i为所指节点p的度加上1,非空树c与T不相交,操作结果为插入c为数T中p节点的第i棵子树
DeleteChild(T,p,i);其中P指向某个节点,i为P的度,操作为,删除T中P的第i棵子树。
************************************************************************************************************/
typedef char TElemType;
typedef int status;
typedef struct TNode{
TElemType data;
struct TNode *lchild;
struct TNode rchild;
}BiTNode,BiTree;//结点结构体
/*bool InitTree(BiTree *T){//建立空树
*T = NULL;
if (!*T)
return false;
return true;
}
*/
void CreateTree(BiTree T){//初始化建立空树,以前序顺序输入各结点数据
TElemType ch;
scanf("%c",&ch);
if (ch == '#')
{
(T) = NULL;
}
else
{
*T = (BiTNode *)malloc(sizeof(BiTNode));
if ((*T) == NULL){
exit(0);
}
(*T) ->data = ch;
CreateTree(&((*T) ->lchild));//先序输入
CreateTree(&((*T) ->rchild));
}
}
void Create(BiTree *T){//初始化功能函数
printf("请按照先序顺序,依次输入每个结点的值,若某个结点为叶子结点,或无某个孩子,则下一个数据用#输入\n");
CreateTree(T);
printf("初始化成功!\n");
}
bool DestroyTree(BiTree *T){//销毁树 后序顺序销毁树,因为后序才能做到最后销毁根节点
if (*T == NULL)//此函数无需退出递归的条件,此为判断初始树是否为空
return true;
DestroyTree(&(*T)->lchild);
//(*T)->lchild = NULL;
DestroyTree(&(*T)->rchild);
//(*T)->rchild = NULL; 可不用,毕竟free之后啥都不剩
free(*T);
return true;
}
void Destroy(BiTree *T){//销毁函数的功能函数
int a;
printf("你将要销毁你所创造的树,你确定吗??(确定输入1,取消输入0)");
scanf("%d",&a);
if (a == 1)
{
DestroyTree(T);
printf("\n销毁成功!\n\n");
}
else
printf("\n取消成功!\n\n");
}
bool ClearTree(BiTree T){//清空树,但不消除根节点的存在
DestroyTree(&(T)->lchild);
DestroyTree(&(T)->rchild);//将根节点的左右子树丢给销毁后就可以既可以留住根结点,又能释放子树中结点的空间
(T)->lchild = (T) ->rchild = NULL;
(T)->data = '#';
if ((*T)->data == '#'&&(*T)->lchild == (*T)->rchild == NULL)
return true;
else
return false;
}
void Clear(BiTree *T){//销毁函数的功能函数
int a;
printf("你将要清空你所创造的树,你确定吗??(确定输入1,取消输入0)");
scanf("%d",&a);
if (a == 1)
{
ClearTree(T);
printf("\n清空成功!\n\n");
}
else
printf("\n取消成功!\n\n");
}
bool TreeEmpty(BiTNode T){//判断是否为空树
if (T.data == '#'&&T.lchild == NULL&&T.rchild == NULL)//判断根节点是否为空
return true;
return false;
}
int TreeDepth(BiTNode T){//返回树的深度
int ld,rd;
if (T.data == '#'&&T.lchild == NULL&&T.rchild == NULL)
return 1;
ld = 1 + TreeDepth(*(T.lchild));
rd = 1 + TreeDepth(*(T.rchild));
return ld > rd ? ld : rd; //判断根节点的左子树和右子树的深度大
}
void Depth(BiTNode T){//深度求解的功能函数
printf("该树的深度为:%d",TreeDepth(T));
printf("\n");
}
TElemType RootTree(BiTNode T){//返回根节点的数据
if (T.data != '#')
return T.data;
return '#';
}
void Root(BiTNode T){//根节点数据的功能函数
printf("根结点的数据为:%c\n",RootTree(T));
}
void meun(){
printf("1.创造树 2.初始化*******\n");
printf("3.销毁树 4.清空树\n");
printf("*****5.判空 6.求深度\n");
printf("7.根结点 8.退出****\n");
}
//TElemType Value(BiTNode T,BiTNode cur_e)
int main(){
int choice;
BiTNode *T;
while(1)
{
meun();
printf("\n请输入你的选择:");
scanf("%d",&choice);
if (choice == 8)
break;
switch(choice){
//case 1: InitTree(&T);break;
case 2: Create(&T);break;
case 3: Destroy(&T);break;
case 4: Clear(&T);break;
case 5: TreeEmpty(*T);break;
case 6: Depth(*T);break;
case 7: Root(*T);break;
default:printf("参数不对!");
}
}
return 0;
}
上面是完整代码:
下面是问题:
void CreateTree(BiTree T){//初始化建立空树,以前序顺序输入各结点数据
TElemType ch;
scanf("%c",&ch);
if (ch == '#')
{
(T) = NULL;
}
else
{
*T = (BiTNode *)malloc(sizeof(BiTNode));
if ((*T) == NULL){
exit(0);
}
(*T) ->data = ch;
CreateTree(&((*T) ->lchild));//先序输入
CreateTree(&((*T) ->rchild));
}
}在这个函数中,我按照先序顺序输入二叉树每一个结点的值,没办法结束。
调试了一下,发现函数中那个scanf();在第一次时被跳过了。那个ch的值成了‘10’
然后那个ch就赋值给了根结点,根本没要输入。
这是为啥呢?我在网上找到的相同的函数,都可以运行。
在main函数中的scanf()后面加个getchar()就可以了,不过不是很清楚是什么原因导致的,并没有在scanf()输入时出现多个数字或者出现空格之类的。