关于递归初步理解
- 先找到终止条件 return 1
- 然后找到关系 f(n)=n*f(n-1)
- 进行递归
三种遍历类型的路径相同 但是访问时机不同
就形成了三种遍历方式 先序遍历 中序遍历 后序遍历
(数遍历的时候可能不可以选哪种遍历类型 例如
计算深度要将父节点深度先计算传给子节点
计算高度要先计算两个子节点的高度再进行比较
拷贝树需要先拷贝两个子节点然后将左右节点连接到子节点
顺序不能变 )
子节点和父节点直接没有关系可以换遍历方式
比如打印 比如计算叶节点个数,不管顺序,只要遍历的节点没有子节点就可以加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