树的定义
树是由一个集合以及在该集合上定义的一种关系构成的,集合中的元素称为树的结点,所定义的关系称为父子关系。父子关系在树的结点之间建立了一个层次结构,在这种层次结构中有一个结点具有特殊的地位,这个结点称为该树的根结点。
数据结构中有很多树的结构,其中包括二叉树、二叉搜索树、2-3树、红黑树等等,本文着重介绍二叉树。
树的基本术语
节点的度:一个节点含有的子树的个数称为该节点的度;
叶节点或终端节点:度为0的节点称为叶节点;
非终端节点或分支节点:度不为0的节点;
双亲节点或父节点:若一个节点含有子节点,则这个节点称为其子节点的父节点;
孩子节点或子节点:一个节点含有的子树的根节点称为该节点的子节点;
兄弟节点:具有相同父节点的节点互称为兄弟节点;
树的度:一棵树中,最大的节点的度称为树的度;
节点的层次:从根开始定义起,根为第1层,根的子节点为第2层,以此类推;
树的高度或深度:树中节点的最大层次;
堂兄弟节点:双亲在同一层的节点互为堂兄弟;
节点的祖先:从根到该节点所经分支上的所有节点;
子孙:以某节点为根的子树中任一节点都称为该节点的子孙。
森林:由m(m>=0)棵互不相交的树的集合称为森林;
树的存储结构
双亲表示法
孩子表示法
二叉树
二叉树是数据结构中一种重要的数据结构,也是树表家族最为基础的结构。
二叉树的定义:二叉树的每个结点至多只有二棵子树(不存在度大于2的结点),二叉树的子树有左右之分,次序不能颠倒。
树基础
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
const int N=5000005;
int n;
int val[N*2],to[N*2],nxt[N*2],head[N],rp;
void add_edg(int x,int y,int z){
to[++rp]=y;val[rp]=z;
nxt[rp]=head[x];head[x]=rp;
}
int dis[N],ans,res;
void dfs(int x,int fa){
res+=dis[x];
for(int i=head[x];i;i=nxt[i]){
int y=to[i];
if(y==fa)continue;
dis[y]=dis[x]+val[i];
dfs(y,x);
}
}
signed main(){
// freopen("4.in","r",stdin);
// freopen("4.out","w",stdout);
scanf("%lld",&n);
fo(i,1,n-1){
int x,y,z;
scanf("%lld%lld%lld",&x,&y,&z);
add_edg(x,y,z);
add_edg(y,x,z);
}
dis[1]=0;dfs(1,0);
// cerr<<"ZZ"<<endl;
printf("%lld\n",res);
dis[2]=res=0;dfs(2,0);
printf("%lld",res);
}
二叉树的遍历
#include<bits/stdc++.h>
using namespace std;
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
const int N=40005;
struct node{
int ls,rs,fa;
char val;
}p[N];
int n;
void dfs1(int x){
// cout<<x<<endl;
if(!x)return ;
printf("%c",p[x].val);
dfs1(p[x].ls);
dfs1(p[x].rs);
}
void dfs2(int x){
if(!x)return ;
dfs2(p[x].ls);
printf("%c",p[x].val);
dfs2(p[x].rs);
}
void dfs3(int x){
if(!x)return ;
dfs3(p[x].ls);
dfs3(p[x].rs);
printf("%c",p[x].val);
}
signed main(){
// cout<<"SS"<<endl;
scanf("%d\n",&n);
// cout<<n<<endl;
fo(i,1,n){
scanf("%c %d %d\n",&p[i].val,&p[i].ls,&p[i].rs);
// cout<<p[i].val<<" "<<p[i].ls<<" "<<p[i].rs<<endl;
}
dfs1(1);printf("\n");
dfs2(1);printf("\n");
dfs3(1);printf("\n");
}
普通树传二叉树
#include<bits/stdc++.h>
using namespace std;
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
const int N=40005;
struct node{int ls,rs;char v;}p[N];
int n;
void dfs1(int x){
if(!x)return ;
printf("%c",p[x].v);
dfs1(p[x].ls);
dfs1(p[x].rs);
}
void dfs2(int x){
if(!x)return ;
dfs2(p[x].ls);
dfs2(p[x].rs);
printf("%c",p[x].v);
}
signed main(){
scanf("%d",&n);getchar();
fo(i,1,n){
scanf("%c",&p[i].v);
int las,now;scanf("%d",&las);
if(las)p[i].ls=las;
while(las){
scanf("%d",&now);
p[las].rs=now;
las=now;
}
getchar();
}
// fo(i,1,n){
// printf("%c\n",p[i].v);
// }
dfs1(1);
printf("\n");
dfs2(1);
}
求后序遍历
#include<bits/stdc++.h>
using namespace std;
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
const int N=4005;
char s1[N],s2[N];
void dfs(int l1,int r1,int l2,int r2){
if(l1>r1)return ;
if(l1==r1){
printf("%c",s1[l1]);
return ;
}
int tmp,ll,rr;
fo(i,l2,r2)if(s1[l1]==s2[i])tmp=i;
ll=tmp-l2;rr=r2-tmp;
dfs(l1+1,l1+ll,l2,tmp-1);
dfs(l1+ll+1,r1,tmp+1,r2);
printf("%c",s1[l1]);
}
signed main(){
scanf("%s%s",s1+1,s2+1);
int len=strlen(s1+1);
dfs(1,len,1,len);
}