电子学会七级-数据结构-二叉树
电子学会七级-数据结构-二叉树
二叉树的存储
二叉树的顺序存储
【深基16.例1】淘汰赛
https://www.luogu.com.cn/problem/P4715
#include <bits/stdc++.h>
using namespace std;
const int N = 7;
int n;
struct Node {
int country, power;
} t[2 << N + 10];
void build() { // build the tree 两个队产生一个胜利对继续比赛
for (int i = n - 1; i > 0; --i) {
int left = i << 1, right = i << 1 | 1;//left 左子树 right右子树 i<<1|1 =i*2+1
if(t[left].power < t[right].power){
t[i].power = t[right].power;
t[i].country = t[right].country;
} else {
t[i].power = t[left].power;
t[i].country = t[left].country;
}
}
}
int main() {
scanf("%d", &n);
n = 1 << n;
for (int i = 0; i < n; ++i) {
scanf("%d", &t[n+i].power);//读入能力值
t[n+i].country = i + 1;//给国家编号 从1开始
}
build();//构建比赛树
if(t[1].power == t[2].power)// 每个国家能力值不同 且 1==1 说明 1和2是一个国家
printf("%d\n", t[3].country);//亚军是第三个国家
else
printf("%d\n", t[2].country);//1 2不是一个国家 亚军是2
return 0;
}
【深基16.例3】二叉树深度
https://www.luogu.com.cn/problem/P4913
#include<bits/stdc++.h>
using namespace std;
struct node{
int l,r;//记录左右节点
}a[1005000];
int n;
int maxdep=-1; //最大深度
void dfs(int cur_node,int step){
if(cur_node==0){//节点为0 即为叶子节点 返回
return ;
}
maxdep=max(maxdep,step);//找最大的深度
dfs(a[cur_node].l,step+1);//搜索左节点,有的话深度就加1
dfs(a[cur_node].r,step+1);//搜索右节点,同上
}
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i].l>>a[i].r;//输入这个节点的左右节点
}
dfs(1,1);//从第一个节点开始,深度初始为1
cout<<maxdep<<endl;
return 0;
}
二叉树的链式存储
新二叉树
https://www.luogu.com.cn/problem/P1305
#include<bits/stdc++.h>
using namespace std;
//n节点数 root 根节点 L根节点左孩子 R根节点右孩子
int n,root,L[100],R[100];
string s;//临时存储输入每行数据
void preorder(int t){//先序遍历
if(t!='*'-'a'){//不是*号 当前子树必然有根 可以输出自己
cout<<char(t+'a');//输出自己
preorder(L[t]);//递归左子树
preorder(R[t]);//递归右子树
}
}
int main(){
cin>>n;//输入节点数
for(int i=0;i<n;i++){//每个节点的左孩子和有孩子
cin>>s;
if(!i){//第一个节点为根节点
root=s[0]-'a';
}
L[s[0]-'a']=s[1]-'a';//当前根节点左孩子
R[s[0]-'a']=s[2]-'a';//当前根节点右孩子
}
preorder(root);//先序输出
return 0;
}
二叉树的遍历
新二叉树
https://www.luogu.com.cn/problem/P1305
#include<bits/stdc++.h>
using namespace std;
//n节点数 root 根节点 L根节点左孩子 R根节点右孩子
int n,root,L[100],R[100];
string s;//临时存储输入每行数据
void preorder(int t){//先序遍历
if(t!='*'-'a'){//不是*号 当前子树必然有根 可以输出自己
cout<<char(t+'a');//输出自己
preorder(L[t]);//递归左子树
preorder(R[t]);//递归右子树
}
}
int main(){
cin>>n;//输入节点数
for(int i=0;i<n;i++){//每个节点的左孩子和有孩子
cin>>s;
if(!i){//第一个节点为根节点
root=s[0]-'a';
}
L[s[0]-'a']=s[1]-'a';//当前根节点左孩子
R[s[0]-'a']=s[2]-'a';//当前根节点右孩子
}
preorder(root);//先序输出
return 0;
}
https://www.luogu.com.cn/problem/P1030

字符串实现
#include<bits/stdc++.h>
using namespace std;
string a,b;
//m 中序 e后序
void dfs(string m,string e) {
if(m.size()>0){
char root=e[e.size()-1];//通过后序 找个字符
int tmp=m.find(root);//找到 根在中序的位置 确定左子树和右子树 和左右子树个数
cout<<root;//根
dfs(m.substr(0,tmp),e.substr(0,tmp));//左 取出 中序 后序 的左子树
dfs(m.substr(tmp+1),e.substr(tmp,e.size()-1-tmp));//右 出 中序 后序 的右子树
}
}
int main() {
// freopen("C:/Users/Administrator/Downloads/P1030_1.in","r",stdin);
// freopen("C:/Users/Administrator/Downloads/P1030_1_1.out","w",stdout);
cin>>a>>b;
dfs(a,b);
return 0;
}
字符数组实现
#include<bits/stdc++.h>
using namespace std;
char a[101],b[101];
/*
中序起点-left、终点-right
后续中 根的位置右端的位置偏移距离 t, b[right-t] 为根
*/
void dfs(int left,int right,int t){
cout<<b[right-t];//后续找根 输出根
for(int i=left;i<=right;i++){
if(a[i]==b[right-t]){//中序中找到根 分成左右两部分
if(i!=left){//如果在中序根的位置不是起点 可以有左子树
dfs(left,i-1,t);//递归左子树
}
if(i!=right){//如果在中序根的位置不是终点 可以有右子树
dfs(i+1,right,t+1);//递归右子树
}
}
}
return;
}
int main(){
cin>>a;//中序
cin>>b;//后续
int n=strlen(a);//中序长度
dfs(0,n-1,0);//0~n-1 根在后续中最后一个位置
}
https://www.luogu.com.cn/problem/UVA536
#include<string>
#include<iostream>
#include<stack>
using namespace std;
string inorder,preorder;
void dfs(string p,string i){//p为先序遍历,i为中序遍历。
if(i.size()<=0)return;//判断是否还有字符。
int root;
//在中序中寻找根
for(int j=0;j<i.size();j++){
if(i[j]==p[0]){//从前到后比较前序根在中序的位置
root=j;
}
}
//左 右 根
dfs(p.substr(1,root),i.substr(0,root));//左子树第一个为根,要从位置“1”开始取。
dfs(p.substr(root+1),i.substr(root+1));//substr(root+1),取出从root+1这个位置开始往后所有字符。
cout<<p[0];//输出根。
}
int main(){
while(cin>>preorder>>inorder){//多组数据。
dfs(preorder,inorder);
cout<<endl;//注意,要换行。
}
}
先序和中序转后序遍历 hdu1710
http://acm.hdu.edu.cn/showproblem.php?pid=1710
算法竞赛入门到进阶 P68
[USACO3.4]美国血统 American Heritage
https://www.luogu.com.cn/problem/P1827
【深基16.例7】普通二叉树(简化版)
https://www.luogu.com.cn/problem/P5076
医院设置
https://www.luogu.com.cn/problem/P1364
遍历问题
https://www.luogu.com.cn/problem/P1229
[NOIP2004 普及组] FBI 树
https://www.luogu.com.cn/problem/P1087
[JLOI2009]二叉树问题
https://www.luogu.com.cn/problem/P3884
绘制二叉树
https://www.luogu.com.cn/problem/P1185
作者:newcode 更多资源请关注纽扣编程微信公众号

从事机器人比赛、机器人等级考试、少儿scratch编程、信息学奥赛等研究学习

浙公网安备 33010602011771号