关于树的那些事(c++)

树的定义
  树是由一个集合以及在该集合上定义的一种关系构成的,集合中的元素称为树的结点,所定义的关系称为父子关系。父子关系在树的结点之间建立了一个层次结构,在这种层次结构中有一个结点具有特殊的地位,这个结点称为该树的根结点。

  数据结构中有很多树的结构,其中包括二叉树、二叉搜索树、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);
}

  • 19
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值