首页 > 其他分享 >二叉树

二叉树

时间:2023-07-24 21:57:06浏览次数:31  
标签:遍历 int 整数 二叉树 编号 节点

一些定义

  1. 先序,中序,后序遍历中的序是遍历根的顺序

  2. 层序遍历就是这个数的bfs序列


树的存储

有很多种存储方式,一般用结构体数组。
数组下标对应这个数的结点,既可以存左儿子右兄弟又可以存左儿子右儿子。
下面来看一些题真切的感受一下代码


例题1 遍历完全二叉树

http://oj.daimayuan.top/course/7/problem/430

题目

给你一棵 n 个节点的完全二叉树,节点的编号为 1 到 n,二叉树的根为 1 号节点。编号为 i (1≤i≤n) 的节点的左儿子如果存在的话,编号为 i+i;编号为 i (1≤i≤n) 的节点的右儿子如果存在的话,编号为 i+i+1。

现在请你求出这棵完全二叉树的先序、中序和后序遍历的结果。

输入格式
一行一个整数 n。

输出格式
输出三行,每行 n 个数代表一种遍历的结果。

第一行为先序遍历的结果,第二行为中序遍历的结果,第三行为后序遍历的结果。

样例输入
7
样例输出
1 2 4 5 3 6 7
4 2 5 1 6 3 7
4 5 2 6 7 3 1
数据规模
对于所有数据,保证 1≤n≤1024。


代码

#include<bits/stdc++.h>

using namespace std;

int a[2000];
int n;

void preorder(int x) //先序
{
	if(x>n) return;
	cout<<x<<" ";
	preorder(2*x);
	preorder(2*x+1);
}

void inorder(int x) //中序
{
	if(x>n) return;
	inorder(2*x);
	cout<<x<<" ";
	inorder(2*x+1);
}

void postorder(int x) //后序 
{
	if(x>n) return;
	postorder(2*x);
	postorder(2*x+1);
	cout<<x<<" ";
}


int main()
{
	cin>>n;
	preorder(1);
	cout<<endl;
	inorder(1);
	cout<<endl;
	postorder(1);
	return 0;
}

例题2遍历一般二叉树

http://oj.daimayuan.top/course/7/problem/431

题目

给你一棵 n 个节点的二叉树,节点的编号为 1 到 n,二叉树的根为 1 号节点。请你求出这棵二叉树的先序、中序和后序遍历的结果。

输入格式
第一行一个整数 n 表示节点数。

接下来 n 行,每行两个整数,第一个整数表示 i 号节点的左儿子的编号,第二个整数表示 i 号节点的右儿子的编号,如果某个数字为 0 表示没有对应的子节点。

输入保证是一棵二叉树。

输出格式
输出三行,每行 n 个数代表一种遍历的结果。

第一行为先序遍历的结果,第二行为中序遍历的结果,第三行为后序遍历的结果。

样例输入
4
2 3
0 0
4 0
0 0
样例输出
1 2 3 4
2 1 4 3
2 4 3 1
数据规模
对于所有数据,保证 1≤n≤1024。


代码

# include<bits/stdc++.h>

using namespace std;
typedef pair<int,int> pii;
const int N = 1200;

pii a[N];
int n;

void preorder(int x)
{
	if(x>n || x == 0) return ;
	cout<<x<<" ";
	preorder(a[x].first);
	preorder(a[x].second);
}

void inorder(int x)
{
	if(x>n || x == 0) return ;
	inorder(a[x].first);
	cout<<x<<" ";
	inorder(a[x].second);
}

void postorder(int x)
{
	if(x>n || x == 0) return ;
	postorder(a[x].first);
	postorder(a[x].second);
	cout<<x<<" ";
}


int main()
{
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		int x,y;scanf("%d%d",&x,&y);
		a[i] = {x,y};
	}
	preorder(1);cout<<endl;
	inorder(1);cout<<endl;
	postorder(1);
	return 0;
}

例题3 二叉树的最近公共祖先 (lca)

http://oj.daimayuan.top/course/7/problem/457

题目

给你一棵 n 个节点的二叉树,节点的编号为 1 到 n,二叉树的根为 1 号节点。

读入 u,v,请求出 u 号节点和 v 号节点的最近公共祖先(Lowest Common Ancestor)。

如果 x 号节点既是 u 号节点的祖先也是 v 号节点的祖先,则称 x 号节点是 u 号节点和 v 号节点的公共祖先。

如果 x 号节点是 u 号节点和 v 号节点的所有公共祖先中深度最深的,则称 x 号节点是 u 号节点和 v 号节点的最近公共祖先。

输入格式
第一行一个整数 n 表示节点数。

接下来 n 行,每行两个整数,第一个整数表示 i 号节点的左儿子的编号,第二个整数表示 i 号节点的右儿子的编号,如果某个数字为 0 表示没有对应的子节点。

输入保证是一棵二叉树。

最后一行两个整数 u,v 表示要求最近公共祖先的两个节点的编号。

输出格式
输出一行一个整数,代表 u 号节点和 v 号节点的最近公共祖先。

样例输入
4
0 2
3 4
0 0
0 0
3 4
样例输出
2
数据规模
对于所有数据,保证 2≤n≤1000,1≤u,v≤n。


代码

# include<bits/stdc++.h>

using namespace std;

int p[1111];
bool st[1111];

int main()
{
	int n;cin>>n;
	p[1] = 1;
	for(int i=1;i<=n;i++)
	{
		int x,y;cin>>x>>y;
		p[x] = i;p[y] = i;
	}	
	int u,v;cin>>u>>v;
	while(u!=1)
	{
		st[u] = true;u = p[u];   //记录一个点的所有祖先
	}
	st[1] = true;
	while(!st[v]) v = p[v];  //遍历另一个点的所有祖先,第一个和u祖先重合的就是最近公共祖先
	cout<<v<<endl;
	return 0;
}

例题4 二叉树子树和

http://oj.daimayuan.top/course/7/problem/459

题目

给你一棵 n 个节点的二叉树,节点的编号为 1 到 n,二叉树的根为 1 号节点。每个节点都有一个权值,i 号节点的权值为 ai,请求出每个节点的子树的权值和(子树内节点的权值的和)。

输入格式
第一行一个整数 n 表示节点数。

接下来 n 行,每行两个整数,第一个整数表示 i 号节点的左儿子的编号,第二个整数表示 i 号节点的右儿子的编号,如果某个数字为 0 表示没有对应的子节点。

输入保证是一棵二叉树。

接下来一行 n 个整数,第 i 个整数 ai 表示 i 号节点的权值。

输出格式
输出一行 n 个整数,第 i 个整数表示 i 号节点的子树的权值和。

样例输入
4
2 3
0 0
4 0
0 0
1 1 1 1
样例输出
4 1 2 1
数据规模
对于所有数据,保证 1≤n≤1000000,1≤ai≤100。


这其实是一道记忆化搜索,涉及到了二叉树


代码

# include<bits/stdc++.h>

using namespace std;
typedef pair<int,int> pii;

const int N = 1e6+10;

pii a[N];
int ans[N];

int solve(int x)
{
    int t = ans[x];
    if(a[x].first) t+=solve(a[x].first);
    if(a[x].second) t+=solve(a[x].second);
    ans[x] = t;
    return t;
}


int main()
{
    int n;cin>>n;
    for(int i=1;i<=n;i++)
    {
        int x,y;cin>>x>>y;
        a[i] = {x,y};
    }
    for(int i=1;i<=n;i++) {int x;cin>>x;ans[i] = x;}
    solve(1);
    for(int i=1;i<=n;i++) cout<<ans[i]<<" ";
    return 0;
}

标签:遍历,int,整数,二叉树,编号,节点
From: https://www.cnblogs.com/algoshimo/p/17578449.html

相关文章

  • 二叉树(四)
    二叉树的顺序结构及堆的实现二叉树的顺序结构普通的二叉树是不适合用数组来存储的,因为可能会存在大量的空间浪费,而完全二叉树更适合使用顺序结构存储。现实中我们通常把堆(一种二叉树)使用顺序结构的数组来存储。需要注意的是这里的堆和操作系统虚拟进程地址空间中的堆是两回事,......
  • 二叉树叶子结点的个数Python
    实现二叉树叶子节点个数的Python代码概述在本文中,我将向你展示如何使用Python来计算二叉树的叶子节点个数。我将向你解释这个过程的每一步,并提供相应的代码示例。步骤下面是计算二叉树叶子节点个数的步骤:步骤描述1创建一个二叉树2定义一个函数来计算叶子节点个......
  • 二叉树典型例题
    输入两棵二叉树的序列AB,判断B是否是A的子结构(NULL不是任何树的子结构) 创建了判断两个节点是否相等的以来函数,在判断是否是子结构的函数里用递归实现。......
  • leetcode104二叉树搜索
    深度优先搜索,递归maxDepth(TreeNode*root){if(!root)return0;returnmax(maxDepth(root->left),maxDepth(root->right))+1;} 广度优先搜索,队列queue<TreeNode*>q;q.push(root);while(!q.empty()){intsize=q.size();while(size>0){Tree......
  • BST(二叉搜索树)、AVL(平衡二叉树)、RBT(红黑树)的区别
    一、二叉搜索树(BST:BinarySortTree)二叉查找树就是左结点小于根节点,右结点大于根节点的一种排序树,也叫二叉搜索树。二叉查找树比普通树查找更快,查找、插入、删除的时间复杂度为O(logN)。但是二叉查找树有一种极端的情况,就是会变成一种线性链表似的结构。此时时间复......
  • 优先队列(基于二叉树的堆)
    代码出处GoSDKcontainer/heap/heap.goInterface接口定义typeInterfaceinterface{sort.InterfacePush(xinterface{})//addxaselementLen()Pop()interface{}//removeandreturnelementLen()-1.}sort.Interface是自定义排序时需要实现的接......
  • 2023.7.14 在二叉树中分配硬币
    借用灵神的图:所以一个直观的想法就是,计算这个子树的硬币个数和节点个数的差的绝对值。这个就是需要传递给父结点的硬币数量。如果这个子树中的子结点也全部执行了这个操作,那么就会把硬币全部集中到当前结点,因此不用考虑子结点中的移动。所以这是个递归算法。(因为要先完成子结......
  • 算法学习day14二叉树part01-94、144、145
    packageSecondBrush.Tree;importjava.util.ArrayList;importjava.util.List;/***94.二叉树的中序遍历*给定一个二叉树的根节点root,返回它的中序遍历。**/publicclassBinaryTreeInorderTraversal_94{publicList<Integer>inorderTraversal(Tre......
  • LeetCode 剑指 Offer 08. 二叉树的下一个节点
    题目:二叉树的下一个节点给定一棵二叉树的其中一个节点,请找出中序遍历序列的下一个节点。(树的后继)注意:如果给定的节点是中序遍历序列的最后一个,则返回空节点;二叉树一定不为空,且给定的节点一定不是空节点;解题思路二叉树的中序遍历:{[左子树],根节点,[右子树]}如图所示......
  • 【算法】根据二叉树的级别返回排序后的元素列表
    根据给定的Node树节点,返回包含按级别排序的树中元素的列表,这意味着根元素位于第一位,然后根子元素(从左到右)位于第二位和第三位,依此类推。1publicclassNode2{3publicNodeLeft;4publicNodeRight;5publicintValue;67publicNode(No......