SDUT数据结构PTA专题(实验五)题解
数据结构与算法A实验五树和二叉树7-1 还原二叉树 (25 分)7-4 树的遍历 (25 分)7-1 还原二叉树 (25 分)#include<bits/stdc++.h>#define ll long longconst int N = 2e5 + 10;using namespace std;int n;// 节点数char pre[N];// 记录前序遍历char mid[N];
·
数据结构与算法A实验五树和二叉树
7-1 还原二叉树 (25 分)
#include<bits/stdc++.h>
#define ll long long
const int N = 2e5 + 10;
using namespace std;
int n; // 节点数
char pre[N]; // 记录前序遍历
char mid[N]; // 记录中序遍历
struct node{ // 树结构体
char data;
node *l,*r;
};
node *buildtree(int len,char *pre,char *mid){ // 建树
node *root=new node;
if(!len) return NULL; // 返回空节点
root->data=pre[0]; // 前序遍历第一个值为根节点
int i;
for(i=0;i<len;i++){ // 在中序遍历中找到对应根节点
if(mid[i]==pre[0]) break;
}
root->l=buildtree(i,pre+1,mid); // 构建左子树
root->r=buildtree(len-i-1,pre+i+1,mid+i+1); // 构建右子树
return root;
}
int get_high(node *root){ // 获取高度
int res=0;
int hl=0,hr=0;
if(!root) res=0;
else{
hl=get_high(root->l); // 获取左子树高度
hr=get_high(root->r); // 获取右子树高度
res=max(hl,hr)+1; // 最高子树高度+1
}
return res; // 返回高度
}
inline void solve(){
cin>>n; // 输入节点数
cin>>pre>>mid; // 输入前序、中序
node *root=buildtree(n,pre,mid); // 建树
cout<<get_high(root)<<endl; // 输出高度
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t=1;
//cin>>t;
while(t--) solve();
return 0;
}
7-2 朋友圈 (25 分)
#include<bits/stdc++.h>
#define ll long long
const int N = 2e5 + 10;
using namespace std;
int vis[N];
int num[N];
void init(int n){ // 初始化
for(int i=0;i<=n;i++) vis[i]=i;
}
int Find(int x){ // 并查集
if(x!=vis[x]) vis[x]=Find(vis[x]);
return vis[x];
}
void Merge(int x,int y){ // 合并
int xx=Find(x);
int yy=Find(y);
if(xx!=yy) vis[xx]=yy;
}
inline void solve(){
int n,m;
cin>>n>>m;
init(n);
while(m--){
int k,x,y;
cin>>k;
if(k){
k--;
cin>>x;
while(k--){
cin>>y;
Merge(x,y);
}
}
}
int maxn=0;
for(int i=1;i<=n;i++){
int x=Find(i);
num[x]++;
maxn=max(maxn,num[x]);
}
cout<<maxn<<endl;
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
solve();
return 0;
}
7-3 修理牧场 (25 分)
#include<bits/stdc++.h>
#define ll long long
const int N = 2e5 + 10;
using namespace std;
inline void solve(){
int n;
cin>>n;
int x;
priority_queue<int,vector<int>,greater<int> >p; //定义优先队列(小顶堆)
for(int i=1;i<=n;i++){ // 输入每段长度,放入队中
cin>>x;
p.push(x);
}
int sum=0; // 记录花费
int a,b;
while(p.size()>1){ // 没有变成一张根木棍
a=p.top();p.pop(); // 取出最小元素
b=p.top();p.pop(); // 取出次小元素
sum+=a+b; // 求当前最小费用
p.push(a+b); // 费用入队
}
cout<<sum<<endl; // 输出答案
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
solve();
return 0;
}
7-4 树的遍历 (25 分)
#include<bits/stdc++.h>
#define ll long long
const int N = 2e5 + 10;
using namespace std;
int n; // 节点数
int post[N]; // 记录后序遍历
int mid[N]; // 记录中序遍历
struct node{ // 树结构体
int data;
node *l,*r;
};
node *buildtree(int len,int *post,int *mid){ // 建树
node *root=new node;
if(!len) return NULL; // 返回空节点
root->data=post[len-1]; // 后序遍历第一个值为根节点
int i;
for(i=0;i<len;i++){ // 在中序遍历中找到对应根节点
if(mid[i]==post[len-1]) break;
}
root->l=buildtree(i,post,mid); // 构建左子树
root->r=buildtree(len-i-1,post+i,mid+i+1); // 构建右子树
return root;
}
void cengxu(node *root){ // 层序遍历(BFS)
queue<node>q; // 定义队列
q.push(*root); //根节点入队
bool tag=0;
while(q.size()){
auto t=q.front(); //取出队首元素
q.pop(); // 队首元素出队
if(tag) cout<<" ";
else tag=1;
cout<<t.data; //输出值
if(t.l) q.push(*t.l); // 若左子树不空,则放入左子树根节点
if(t.r) q.push(*t.r); // 若右子树不空,则放入右子树根节点
}
cout<<endl;
}
inline void solve(){
cin>>n; // 输入节点数
for(int i=0;i<n;i++) cin>>post[i];
for(int i=0;i<n;i++) cin>>mid[i];
node *root=buildtree(n,post,mid); // 建树
cengxu(root); //层序遍历
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t=1;
//cin>>t;
while(t--) solve();
return 0;
}
7-5 部落 (25 分)
#include<bits/stdc++.h>
#define ll long long
const int N = 2e5 + 10;
using namespace std;
int vis[N];
void init(int n){ // 初始化
for(int i=0;i<=n;i++) vis[i]=i;
}
int Find(int x){ // 并查集
if(x!=vis[x]) vis[x]=Find(vis[x]);
return vis[x];
}
void Merge(int x,int y){ // 合并
int xx=Find(x);
int yy=Find(y);
if(xx!=yy) vis[xx]=yy;
}
set<int>peo,num; // 记录人数和部落数
inline void solve(){
int n;
cin>>n;
init(100000);
for(int i=1;i<=n;i++){
int k;
cin>>k;
if(k){
int x,y;
cin>>x;
peo.insert(x);
k--;
while(k--){
cin>>y;
peo.insert(y); // 记录人数
Merge(x,y); // 合并
}
}
}
for(int i=1;i<=peo.size();i++) num.insert(Find(i)); // 记录部落数
cout<<peo.size()<<" "<<num.size()<<endl; // 输出人数和部落数
int q;
cin>>q; // q次询问
while(q--){
int x,y;
cin>>x>>y;
if(Find(x)!=Find(y)) cout<<"N"<<endl; // 不在一个部落
else cout<<"Y"<<endl; // 在一个部落
}
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
solve();
return 0;
}
7-6 交换二叉树中每个结点的左孩子和右孩子 (20 分)
#include<bits/stdc++.h>
#define ll long long
const int N = 2e5 + 10;
using namespace std;
typedef struct node{
char data;
node *l,*r;
}*Bitree;
string s;
int pos;
void buildtree(Bitree &root){ // 建树
if(s[pos]=='#'){
root=NULL;
pos++;
}else{
root=new node;
root->data=s[pos++];
buildtree(root->l); // 建立左子树
buildtree(root->r); // 建立右子树
}
}
void midorder(Bitree root){ // 中序遍历
if(root){
midorder(root->l);
cout<<root->data;
midorder(root->r);
}
}
void exmidorder(Bitree root){ // 反向中序遍历(即交换左右子树)
if(root){
exmidorder(root->r);
cout<<root->data;
exmidorder(root->l);
}
}
inline void solve(){
cin>>s;
pos=0;
node *root=new node;
buildtree(root);
midorder(root);
cout<<endl;
exmidorder(root);
cout<<endl;
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
solve();
return 0;
}
7-7 列出叶结点 (25 分)
#include<bits/stdc++.h>
#define eb emplace_back
#define ll long long
const int N = 2e5 + 10;
using namespace std;
struct node{
int l,r;
}tree[N];
int val[N];
queue<int>q;
vector<int>res;
void BFS(){ // 层序遍历找叶子
while(q.size()){
auto t=q.front();
q.pop();
if(tree[t].l==-1&&tree[t].r==-1) res.eb(t);
if(tree[t].l!=-1) q.push(tree[t].l);
if(tree[t].r!=-1) q.push(tree[t].r);
}
}
inline void solve(){
int n;
cin>>n;
char a,b;
for(int i=0;i<n;i++){ // 建树
cin>>a>>b;
if(a=='-') tree[i].l=-1;
else{
tree[i].l=a-'0';
val[a-'0']=1;
}
if(b=='-') tree[i].r=-1;
else{
tree[i].r=b-'0';
val[b-'0']=1;
}
}
int root;
for(int i=0;i<n;i++){ // 找根节点
if(!val[i]){
root=i;
break;
}
}
q.push(root);
BFS();
bool tag=0;
for(auto i:res){ // 输出结果
if(tag) cout<<" ";
else tag=1;
cout<<i;
}
cout<<endl;
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
solve();
return 0;
}
7-8 建立与遍历二叉树 (25 分)
#include<bits/stdc++.h>
#define ll long long
const int N = 2e5 + 10;
using namespace std;
typedef struct node{
char data;
node *l,*r;
}*Bitree;
string s;
int pos;
void buildtree(Bitree &root){ // 建树
if(s[pos]=='#'){
root=NULL;
pos++;
}else{
root=new node;
root->data=s[pos++];
buildtree(root->l); // 建立左子树
buildtree(root->r); // 建立右子树
}
}
void midorder(Bitree root){ // 中序遍历
if(root){
midorder(root->l);
cout<<root->data;
midorder(root->r);
}
}
inline void solve(){
cin>>s;
pos=0;
node *root=new node;
buildtree(root);
midorder(root);
cout<<endl;
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
solve();
return 0;
}
7-9 完全二叉树的层序遍历 (25 分)
#include<bits/stdc++.h>
#define ll long long
const int N = 2e5 + 10;
using namespace std;
int n;
int root[N];
void buildtree(int x){ // 递归建树
if(x>n) return ;
buildtree(2*x);
buildtree(2*x+1);
cin>>root[x];
}
inline void solve(){
cin>>n;
buildtree(1); // 建树
for(int i=0;i<n;i++){ // 输出结果
if(i) cout<<" ";
cout<<root[i+1];
}
cout<<endl;
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
solve();
return 0;
}

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐
所有评论(0)