二叉树的建立与销毁(C语言)

二叉树的建立

在讲解二叉树的建立前,请读者务必要先思考一个问题

思考问题:如何确定一个二叉树,如果只看 前序 或 中序 或 后序遍历 三种之一能够确定唯一一个二叉树的形状吗?
其中:
前序遍历结果:ADEBCF
中序遍历结果:DEACFB
后序遍历结果:EDFCBA

================================================
解:
单凭一种遍历的结果,无法确定一个二叉树,当满足以下两种情况即可满足确定。
条件1:前序和中序
条件2:中序和后序

为什么呢?证明如下:
步骤1:通过前序或后序遍历可确定根结点。(前序的第一个遍历结果,后序最后一个遍历结果)
步骤2:通过中序遍历可确定结点下的左子树和右子树部分。(通过前序和后序获得的根结点,在中序遍历中对应的该根节点位置分割左右子树)
以此类推,可确定二叉树的形状,读者不妨验证一下,加深理解。
将已知结果分为三部分,根节点和左右子树的判断,逐渐减少未知结点,重复利用前序或后序判断谁是根节点,在用中序判断谁是左子树或右子树。
二叉树形状:

Alt

================================================

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;
}

  • 10
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值