二叉树
《大话数据结构》中对树的解释:
二叉树是一种特殊的树,特点是每个节点最多有两个儿子,左边的为左儿子,右边的为右儿子,或者说每个节点最多有两个子树;
更严格的递归定义是:二叉树要么为空,要么由根节点、左子树和右子树组成,而左子树和右子树又分别是一颗二叉树
二叉树的遍历:
二叉树的遍历:
先序遍历:根左右
中序遍历:左根右
后序遍历:左右根
层序遍历:
刷题:
思路:
题目给出了一个二叉树的中序排列和后序排列,由后序“左右根”的特点知后序排列的最后一个字符串总为一个根,于是接着在中序遍历中找到这个根,又由中序“左根右”的特点知该根的左右分别为左子树和右子树。那么就可以用一个递归来分开左右子树,具体操作看代码
#include<stdio.h>
#include<string.h>
char middle[40], last[40]; //分别存中序遍历字符串和后序遍历字符串
void serch(int mf, int me, int lf, int le) { //mf,me分别为该子树中序遍历起止点,lf和le分别为后序遍历起止点
int mid;//中序遍历中左右子树的根
printf("%c", last[le]); //由后序遍历特点可知,后序遍历的最后一个为根,输出
for (int i = mf; i <= me; i++) { //在中序遍历中找那个根
if (middle[i] == last[le]) {
mid = i;
break;
}
}
int h = lf + mid - mf;//后序遍历中左右子树的界限(看了大佬题解才知道的)
if (mid - 1 >= mf && h - 1 >= lf) { //先看该树的左子树(为啥是先左子树?因为题目要求的是先序遍历输出该二叉树)
serch(mf, mid - 1, lf, h - 1);
}
if (mid + 1 <= me && h <= le - 1) {//右子树
serch(mid + 1, me, h, le - 1);
}
}
int main() {
gets(middle);
gets(last);
int mlen = strlen(middle), flen = strlen(last);
serch(0, mlen - 1, 0, flen - 1); //开始拆分
return 0;
}
思路:
根据题给数据还原二叉树,然后用一个递归搜索回溯从根搜索到叶结点,每当进入一个结点,深度加1,当进入叶结点时进行最大深度更新,最后输出最大深度即可:
#include<stdio.h>
#define shu 1000000+20
int n, dpmax = 0;
struct tree {
int left;
int right;
} tr[shu];
void serch(int numb, int dep) { //numb为要搜索的结点,dep为当前节点深度
if (tr[numb].left == 0 && tr[numb].right == 0) { //是叶结点
if (dep > dpmax) {
dpmax = dep;
}
return;
}
serch(tr[numb].left, dep + 1);//搜索左子树
serch(tr[numb].right, dep + 1);//搜索右子树
}
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; i++) { //建立一个树
scanf("%d %d", &tr[i].left, &tr[i].right);
}
serch(1, 1);
printf("%d", dpmax + 1);
return 0;
}