树(括号凑字数

由于太水,建议吃沙子的时候看

树的特性:节点=边数+1,一个点对多个点……

二叉树树的一种类型,每个点的度不大于2。
1.先序遍历:以根左右的顺序进行遍历
1 2 4 5 3 6 7
2.中序遍历:以左根右的方式进行遍历
4 2 5 1 6 3 7
3.后序遍历:以左右根的方式进行遍历
4 5 2 6 7 3 1

1.通过先序、中序求后序
1 2 4 5 3 6 7
4 2 5 1 6 3 7

先序遍历中的第一个数是根节点,在中序遍历中找这个点,在这个点左边的是左子树,在右边的是右子树。425是左子树,然后在这里边找2,所以4是2的左子树,5是2的右子树。再看另一边,637是右子树,在里边找3,3左边的6是3的左子树,7是3的右子树。


2.通过后序、中序求先序
4 5 2 6 7 3 1
4 2 5 1 6 3 7

后序遍历最后一个点是根节点,在中序里找这个数,左边的是左子树,右边的是右子树,然后用上面的方法继续。

3.不能通过先序、后序求中序,这样求出来的答案是不唯一的。

满二叉树
每一个节点要么是一个叶子节点,要么是一个出度为2的节点。
且一定拥有(2^n)-1个节点,一定有log2(n+1)层。

完全二叉树
前n-1层是满二叉树,最后一层的节点集中在左侧。

二叉树问题
这道题是一道综合题,要用到深度,宽度,和两点之间的距离
这道题输入可以使用vector输入

cin>>n;
for(int i=2;i<=n;i++){
	int x,y;
	cin>>x>>y;
	a[x].push_back(y);
	a[y].push_back(x);
}

使用dfs求深度。
每到达一个点,就用ans取ans和这个点的深度的最大值。然后再前往这个点能到达的点。

void dfs(int x,int dep){
	ans=max(ans,dep);
	for(int i=0;i<a[x].size();i++)
		if(!vis[a[x][i]]){
			vis[a[x][i]]=1;
			//标记点
			dfs(a[x][i],dep+1);
	}
}

使用dfs求宽度
每检测到一个点,就让w[dep]加一。并让ans取ans和w[dep]中的最大值。

void dfs1(int x,int dep){
	for(int i=0;i<a[x].size();i++)
		if((!vis[a[x][i]])){
			w[dep]++;
			//让该层的数量统计加一
			ans=max(ans,w[dep]);
			//取最大值
			vis[a[x][i]]=1;
			//标记点
			dfs1(a[x][i],dep+1);
		}
}

使用bfs求两点之间最短距离
像走迷宫一样搜索,只不过每个点的到达位置规定好了而已。

void bfs(){
	queue<node> q;
	q.push(node{s,0});
	while(!q.empty()){
		node now=q.front();
		q.pop();
		for(int i=0;i<a[now.x].size();i++){
			if(a[now.x][i]==e){
				cout<<now.step+1;
				return;
			}
			if(!vis[a[now.x][i]]){
				vis[a[now.x][i]]=1;
				q.push(node{a[now.x][i],now.step+1});
			}
		}
	}
}
//最后把他们的结果一次输出,别忘了初始化。
5 个赞
呵呵
往下看
太coola

水货满满学废了

3 个赞

还是我的干一点花了一坤年才整理出来的https://discourse.xinyoudui.com/t/topic/7407/1

3 个赞