【数据结构】二叉树的遍历、求深度、求高度

关于递归初步理解

  1. 先找到终止条件 return 1
  2. 然后找到关系 f(n)=n*f(n-1)
  3. 进行递归

三种遍历类型的路径相同 但是访问时机不同
就形成了三种遍历方式 先序遍历 中序遍历 后序遍历
(数遍历的时候可能不可以选哪种遍历类型 例如
计算深度要将父节点深度先计算传给子节点
计算高度要先计算两个子节点的高度再进行比较
拷贝树需要先拷贝两个子节点然后将左右节点连接到子节点
顺序不能变 )
子节点和父节点直接没有关系可以换遍历方式
比如打印 比如计算叶节点个数,不管顺序,只要遍历的节点没有子节点就可以加1

二叉树类型定义

typedef struct TreeNode
{
	int data;//数据
	int depth;//节点深度
	TreeNode* lchild;//左节点
	TreeNode* rchild;//右节点
}TreeNode;
typedef TreeNode* Tree;

二叉树遍历函数

void tree_printf(TreeNode* tree)
{
	if (tree == NULL)
	{
		return;
	}
	
	tree_printf(tree->lchild);
	tree_printf(tree->rchild);
	printf("%d ", tree->data);
	//注意 print相对于左右print的位置决定了遍历顺序
	return;
}

计算叶子节点数量

void tree_count(TreeNode* tree, int* sum)
{
	if (tree == NULL)//返回条件
	{
		return;
	}
	//操作
	if (tree->lchild == NULL || tree->rchild == NULL)
	{
		(*sum)++;//注意 取地址再加 相当于加sum的值
	}
	tree_count(tree->lchild, sum);
	tree_count(tree->rchild, sum);
}

求树的高度(视频教程中介绍的内容)
(父节点的高度会比较大,受到子节点影响)

int tree_height2(TreeNode* tree)
{
	if (tree == NULL)
	{
		return 0;
	}
	int ret = 0;
	int lret = tree_height2(tree->lchild);
	int rret = tree_height2(tree->rchild);
	ret = 1 + (lret > rret ? lret : rret);//注意 双目运算符优先级低于等于 优先级高的先算 要加括号
	//子树中深度较大的加1
	return ret;
}

求每个节点的深度(求每个节点的深度)
和子节点无关 和父节点有关 父节点的深度低

void tree_height1(TreeNode* tree,int d)
{
	if (tree == NULL)
	{
		return;
	}
	tree->depth = d + 1;//数的深度等于父节点的深度+1
	printf("\ndata%d depth%d\n", tree->data, tree->depth);
	tree_height1(tree->lchild, tree->depth);//将父节点的深度传给子节点
	tree_height1(tree->rchild, tree->depth);
}

数的复制

TreeNode* tree_copy(TreeNode* tree)
{
	if (tree == NULL)
	{
		return NULL;
	}//返回条件
	TreeNode* tmp;
	tmp = (TreeNode*)malloc(sizeof(TreeNode));
	memset(tmp, 0, sizeof(TreeNode));//内存记得置成0
	if (tmp == NULL)
	{
		printf("error\n");
		return NULL;
	}
	tmp->data = tree->data;
	tmp->lchild = tree_copy(tree->lchild);
    tmp->rchild = tree_copy(tree->rchild);
	return tmp;
}

测试函数

	TreeNode t1, t2, t3, t4, t5,t6;


	memset(&t1, 0, sizeof(TreeNode));//注意 遍历时将初始的左右子节点置0
	memset(&t2, 0, sizeof(TreeNode));
	memset(&t3, 0, sizeof(TreeNode));
	memset(&t4, 0, sizeof(TreeNode));
	memset(&t5, 0, sizeof(TreeNode));
	memset(&t6, 0, sizeof(TreeNode));
	t1.data = 1;
	t2.data = 2;
	t3.data = 3;
	t4.data = 4;
	t5.data = 5;
	t6.data = 6;

	t1.lchild = &t2;
	t1.rchild = &t3;
	t2.lchild = &t4;
	t2.rchild = &t5;
	t5.lchild = &t6;
	//数的遍历打印
	printf("数的遍历打印\n");
	tree_printf(&t1);

	//求数的节点数
	printf("\n\n求数的节点数");
	int sum = 0;
	tree_count(&t1, &sum);
	printf("\ncount=%d\n", sum);

	//求数的深度
	printf("\n求数的深度");
	int d = 0;
	tree_height1(&t1,d);
	
	//
	printf("\n求数的高度\n");
	int ret=tree_height2(&t1);
	printf("max=%d\n", ret);

	//数的复制
	printf("\n树的复制\n");
	TreeNode* tmp = NULL;
	tmp = tree_copy(&t1);
	tree_printf(tmp);
	return 0;

运行结果

数的遍历打印
4 6 5 2 3 1

求数的节点数
count=4

求数的深度
data1 depth1

data2 depth2

data4 depth3

data5 depth3

data6 depth4

data3 depth2

求数的高度
max=4

树的复制
4 6 5 2 3 1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值