二叉树
-
节点(Node):树形结构中的基本单位,可以表示数据元素或对象。节点可以包含一个或多个子节点。
-
根节点(Root Node):树的顶层节点,它没有父节点,是整个树的起点。
-
子节点(Child Node):树中每个节点都可以有零个或多个子节点,子节点是位于其父节点下方的节点。
-
父节点(Parent Node):每个节点(除了根节点)都有一个父节点,父节点是它的直接上一级节点。
-
兄弟节点(Sibling Node):具有相同父节点的节点被称为兄弟节点。换句话说,它们是同一级别的节点。
-
叶节点(叶子节点,Leaf Node):没有子节点的节点被称为叶节点,它们位于树的末端。
-
子树(Subtree):树中的任何节点及其所有后代节点构成了一个子树,这个子树也是一个有效的树。
-
深度(Depth):一个节点到根节点的路径的长度被称为该节点的深度。根节点的深度通常为0,直接子节点的深度为1,以此类推。
-
高度(Height):树的高度是树中任何节点的最大深度。也就是说,树的高度是从根节点到最深的叶节点的最长路径的长度。
-
祖先节点(Ancestor Node):一个节点的祖先节点是指从根节点到该节点的路径上的所有节点,包括该节点的父节点。
-
后代节点(Descendant Node):一个节点的后代节点是指该节点的所有子节点及其子节点的子节点,以此类推。
- 树的中序遍历是按照左子树,根,右子树的顺序访问节点;
- 树的前序遍历是按照根,左子树,右子树的顺序访问节点;
- 树的后序遍历是按照左子树,右子树,根的顺序访问节点。
二叉树深度:
//二叉树深度: //https://www.luogu.com.cn/problem/P4913 #include<bits/stdc++.h> using namespace std; const int N=2e5+10; int n,m,res; struct node { int l,r; }tr[N]; void dfs(int u,int now) { if(u==0) return; res=max(res,now); dfs(tr[u].l,now+1),dfs(tr[u].r,now+1); } int main() { cin>>n; for(int i=1;i<=n;i++) cin>>tr[i].l>>tr[i].r; dfs(1,1); cout<<res; return 0; } //邻接表 #include<bits/stdc++.h> using namespace std; const int N=2e5+10; int n,m,res; int e[N],ne[N],idx,h[N]; void add(int a,int b) { e[idx]=b,ne[idx]=h[a],h[a]=idx++; } void dfs(int u,int now) { res=max(now,res); for(int i=h[u];~i;i=ne[i]){ int j=e[i]; dfs(j,now+1); } } int main() { cin>>n; memset(h,-1,sizeof h); for(int i=1;i<=n;i++){ int u,v; cin>>u>>v; if(u==0&&v==0) continue; add(i,u),add(i,v); } dfs(1,1); cout<<res; return 0; }
二叉树遍历
//https://www.luogu.com.cn/problem/P1827 //我们要根据中序遍历建树,并且通过前序遍历寻找节点 //由于后序遍历是左 右 根,所以我们先遍历左边在遍历右边最后输出根节点即可 #include<bits/stdc++.h> using namespace std; const int N=2e5+10; int n,m,res,num; string a,b; void dfs(int qian_l,int qian_r,int zhong_l,int zhong_r) //l-r表示遍历区间 { if(qian_l>qian_r||zhong_l>zhong_r) return; //不合法 int pos=a.find(b[qian_l]); //在中序遍历中寻找每个树的根节点,一步一步的向下遍历 dfs(qian_l+1,qian_l+pos-zhong_l,zhong_l,pos-1); //遍历左区间 dfs(qian_l+pos-zhong_l+1,qian_r,pos+1,zhong_r); //遍历右区间 //ABEDFCHG //CBADEFGH //由于根节点一开始是C,所以第一次遍历的左区间中dfs的第一个区间是: // 前序遍历区间中的 BADEF,中序遍历区间中的 BADEF //右区间同理 cout<<a[pos]; } int main() { cin>>a>>b; //读入中序和前序 int l=a.size()-1; dfs(0,l,0,l); return 0; }
//https://www.luogu.com.cn/problem/P1030 #include<bits/stdc++.h> using namespace std; const int N=2e5+10; string a,b,c; int n,res; void dfs(int hou_l,int hou_r,int zhong_l,int zhong_r) { if(hou_l>hou_r||zhong_l>zhong_r) return; int pos=a.find(b[hou_r]); cout<<a[pos]; dfs(hou_l,hou_l+pos-zhong_l-1,zhong_l,pos-1); dfs(hou_l+pos-zhong_l,hou_r-1,pos+1,zhong_r); } int main() { cin>>a>>b; int l=a.size(); dfs(0,l-1,0,l-1); return 0; }
//https://www.luogu.com.cn/problem/P1305 #include<bits/stdc++.h> #define int long long using namespace std; int n; char root; map<char,pair<char,char>>tr; void dfs(char u) { cout<<u; if(tr[u].first!='*') dfs(tr[u].first); if(tr[u].second!='*') dfs(tr[u].second); } signed main() { cin>>n; char b,c; cin>>root>>b>>c; tr[root]={b,c}; for(int i=1;i<n;i++){ char a,b,c; cin>>a>>b>>c; tr[a]={b,c}; } dfs(root); return 0; }
//https://www.luogu.com.cn/problem/P1229 //考虑一点,如果说一个节点只有一个子节点,那么这个子节点既可以当左子节点也可以当右子节点 //所以此时问题就转化成 -> 寻找只有一个子节点的节点数,最后的可能性为2^n,倘若是一棵完全二叉树,则为2^0=1 //考虑如何找只有一个子节点: //如果先序排列是AB,此时有两种可能性,A为B的父节点,A B是兄弟节点 //如果后序排列是BA,则直接排除兄弟节点的可能,因为如果是兄弟节点,顺序应该是AB,因为A在左 //所以此时B节点就是A的唯一子节点,得证 #include<bits/stdc++.h> #define int long long using namespace std; const int N=2e5+10; int n,m,res; string s,ss; signed main() { cin>>s>>ss; for(int i=0;i<s.size();i++) for(int j=1;j<s.size();j++) if(s[i]==ss[j]&&s[i+1]==ss[j-1]) res++; cout<<(1<<res); return 0; }
//https://www.luogu.com.cn/problem/P3884 #include<bits/stdc++.h> using namespace std; const int N=2e5+10; int e[N],ne[N],idx,h[N],num[N],dist[N]; int fa[N][16],n,m,res,ans,dis,st,ed; int dep,wid; void add(int a,int b) { e[idx]=b,ne[idx]=h[a],h[a]=idx++; } void bfs() { memset(dist,0x3f,sizeof dist); queue<int>que; que.push(1),dist[1]=1,dist[0]=0; while(!que.empty()){ int now=que.front(); que.pop(); for(int i=h[now];~i;i=ne[i]){ int j=e[i]; if(dist[j]>dist[now]+1){ dist[j]=dist[now]+1; dep=max(dep,dist[j]); fa[j][0]=now,que.push(j); for(int k=1;k<=15;k++) fa[j][k]=fa[fa[j][k-1]][k-1]; } } } } int lca(int a,int b) { if(dist[a]<dist[b]) swap(a,b); for(int k=15;k>=0;k--) if(dist[fa[a][k]]>=dist[b]) a=fa[a][k]; if(a==b) return a; for(int k=15;k>=0;k--) if(fa[a][k]!=fa[b][k]) a=fa[a][k],b=fa[b][k]; return fa[a][0]; } int main() { memset(h,-1,sizeof h); cin>>n; for(int i=1;i<n;i++){ int u,v; cin>>u>>v; add(u,v); } bfs(); for(int i=1;i<=n;i++){ num[dist[i]]++; if(wid<num[dist[i]]) wid=num[dist[i]]; } cin>>st>>ed; cout<<dep<<endl<<wid<<endl<<(dist[st]-dist[lca(st,ed)])*2+dist[ed]-dist[lca(st,ed)]; return 0; }