1月2日 自习总结

二叉树

《大话数据结构》中对树的解释:

 二叉树是一种特殊的树,特点是每个节点最多有两个儿子,左边的为左儿子,右边的为右儿子,或者说每个节点最多有两个子树;

更严格的递归定义是:二叉树要么为空,要么由根节点、左子树和右子树组成,而左子树和右子树又分别是一颗二叉树

二叉树的遍历:

二叉树的遍历:

先序遍历:根左右

中序遍历:左根右

后序遍历:左右根

层序遍历:

刷题:

[NOIP2001 普及组] 求先序排列 - 洛谷

 思路:

题目给出了一个二叉树的中序排列和后序排列,由后序“左右根”的特点知后序排列的最后一个字符串总为一个根,于是接着在中序遍历中找到这个根,又由中序“左根右”的特点知该根的左右分别为左子树和右子树。那么就可以用一个递归来分开左右子树,具体操作看代码

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

【深基16.例3】二叉树深度 - 洛谷

 思路:

根据题给数据还原二叉树,然后用一个递归搜索回溯从根搜索到叶结点,每当进入一个结点,深度加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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值