PAT A1099 Build A Binary Search Tree [二叉搜索树]

题目描述

链接
给出一棵二叉搜索树(给出每个结点的左右孩子),且已知根结点为0,求并且给出应该插入这个二叉搜索树的数值,求这棵二叉树的层序遍历

分析

  • 给了下标,肯定用静态数组实现
  • 利用的性质:二叉搜索树中序遍历肯定有有序
    • 对所给key进行排序,得到中序遍历次序
    • 利用中序遍历次序,对树进行遍历,可以得到存储次序(用\(index\)保存)(把访问根节点操作变成赋值操作),这个存储次序就是层序遍历顺序
    • 再纠正一点,不是中序遍历建树,树实际是知道结构了,就是每个结点的儿子都知道了。单纯的中序是无法唯一确定一棵树的
    • 同时,存储次序这件事不止是完全二叉树才有的,实际上只要用类似完全二叉树那样存储结点(即满足\(i\),\(2i\),\(2i+1\)那种)的都有,只是其他树浪费空间多。这里可以用一个index来表示该结点的“存储次序”,注意,并不是真的按照这样去存静态结点
      ```c++

      include<bits/stdc++.h>

      using namespace std;

const int maxn = 105;
struct node{
int l, r, idx, data;
}nodes[maxn];
int a[maxn], b[maxn];
int n, l, r;
int len;
void dfs(int root, int idx){
if(root == -1) return;
dfs(nodes[root].l, idx2+1);
nodes[root].idx = idx;
nodes[root].data = a[len++];
dfs(nodes[root].r, idx
2+2);
}

bool cmp(node a, node b){
return a.idx < b.idx;
}

int main(){
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d%d",&nodes[i].l, &nodes[i].r);
}
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
}
sort(a,a+n);
dfs(0,0);
sort(nodes, nodes+n, cmp);
for(int i=0;i<n;i++){
printf("%d",nodes[i].data);
if(i!=n-1) printf(" ");
}
printf("\n");
}

```

  • BFS的想法
    • 排序,然后中序遍历赋值(node[i].data),将数据存在ans中,然后层序遍历得到结果
#include<bits/stdc++.h>
using namespace std;

const int maxn = 105;
int n, l, r, a[maxn];
struct node{
   int data;
   int l,r;
}nodes[maxn];
vector<int> ans;

void bfs(){
   queue<int> q;
   q.push(0);
   while(!q.empty()){
       int id = q.front();
       q.pop();
       ans.push_back(nodes[id].data);
       if(nodes[id].l != -1) q.push(nodes[id].l);
       if(nodes[id].r != -1) q.push(nodes[id].r);
   }
}
int len;
void inorder(int root){
   if(root == -1) return;
   inorder(nodes[root].l);
   nodes[root].data = a[len++];
   inorder(nodes[root].r);
}

int main(){
   scanf("%d",&n);
   for(int i=0;i<n;i++){
       scanf("%d%d",&nodes[i].l, &nodes[i].r);
   }
   for(int i=0;i<n;i++){
       scanf("%d",&a[i]);
   }
   inorder(0);
   bfs();
   for(int i=0;i<ans.size();i++){
       if(i==0) printf("%d",ans[i]);
       else printf(" %d",ans[i]);
   }
   printf("\n");

}

转载于:https://www.cnblogs.com/doragd/p/11285500.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值