L2-004 这是二叉搜索树吗? (25 分)
思路:
按照题目所给的先序遍历结果进行每次插入节点进行建树,然后先序遍历判断是否合法即可
镜像遍历只要改变左右子树的遍历顺序就好了
code:
#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
#define ull unsigned long long
#define ld long double
#define all(x) x.begin(), x.end()
#define mem(x, d) memset(x, d, sizeof(x))
#define eps 1e-6
using namespace std;
const int maxn = 2e6 + 9;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
ll n, m;
int a[maxn], cnt;
struct node{
int val, l, r;
}tr[maxn];
int path[maxn];
void add(int x, int p){
if(tr[x].val < tr[p].val){
if(tr[p].l) add(x, tr[p].l);
else tr[p].l = x;
}
else
{
if(tr[p].r) add(x, tr[p].r);
else tr[p].r = x;
}
}
void dfs1(int p){// 先序
path[++cnt] = tr[p].val;
if(tr[p].l) dfs1(tr[p].l);
if(tr[p].r) dfs1(tr[p].r);
}
void dfs2(int p){// 后序
if(tr[p].l) dfs2(tr[p].l);
if(tr[p].r) dfs2(tr[p].r);
path[++cnt] = tr[p].val;
}
void dfs3(int p){// 镜像先序
path[++cnt] = tr[p].val;
if(tr[p].r) dfs3(tr[p].r);
if(tr[p].l) dfs3(tr[p].l);
}
void dfs4(int p){// 镜像后序
if(tr[p].r) dfs4(tr[p].r);
if(tr[p].l) dfs4(tr[p].l);
path[++cnt] = tr[p].val;
}
void work()
{
cin >> n;
for(int i = 1; i <= n; ++i) cin >> tr[i].val;
for(int i = 2; i <= n; ++i) add(i, 1);// 建树
bool f = 1;
dfs1(1);
for(int i = 1; i <= cnt; ++i) if(path[i] != tr[i].val) f = 0;
if(f){// 符合先序结果
cnt = 0;
dfs2(1);
cout << "YES\n";
for(int i = 1; i <= n; ++i)
cout << path[i] << " \n"[i==n];
return;
}
cnt = 0; f = 1;
dfs3(1);
for(int i = 1; i <= n; ++i) if(path[i] != tr[i].val) f = 0;
if(f){// 符合镜像先序
cnt = 0;
dfs4(1);
cout << "YES\n";
for(int i = 1; i <= n; ++i) cout << path[i] << " \n"[i==n];
return;
}
cout << "NO\n";
}
int main()
{
ios::sync_with_stdio(0);
// int TT;cin>>TT;while(TT--)
work();
return 0;
}
L2-006 树的遍历 (25 分)
思路:
还原二叉树
模拟还原二叉树的过程,递归建树
code:
#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
#define ls (p << 1)
#define rs (p << 1 | 1)
using namespace std;
const int maxn = 1e5 + 9;
const int mod = 1e9 + 7;
ll n, m;
int last[maxn], mid[maxn], ans[maxn];
void build(int l, int r, int rt, int p)
{
if(l > r) return;
int pos = l;
while(pos <= r && mid[pos] != last[rt]) ++pos;
ans[p] = last[rt];
build(l, pos - 1, rt - (r - pos + 1), ls);
build(pos + 1, r, rt - 1, rs);//右子树根就是 rt-1
}
void work()
{
memset(ans, -1, sizeof(ans));
cin >> n;
for(int i = 1; i <= n; ++i) cin >> last[i];
for(int i = 1; i <= n; ++i) cin >> mid[i];
build(1, n, n, 1);
vector <int> v;
for(int i = 1; i < maxn; ++i) if(ans[i] != -1)
v.push_back(ans[i]);
for(int i = 0; i < (int)v.size() - 1; ++i) cout << v[i] << " ";
cout << v.back() << endl;
}
int main()
{
ios::sync_with_stdio(0);
//int TT;cin>>TT;while(TT--)
work();
return 0;
}
L2-011 玩转二叉树 (25 分)
思路:
和上边的题差不多,只需要把建树过程中的左右子树节点编号交换即可
code:
#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
#define ull unsigned long long
#define ld long double
#define all(x) x.begin(), x.end()
#define mem(x, d) memset(x, d, sizeof(x))
#define eps 1e-6
using namespace std;
const int maxn = 2e6 + 9;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
ll n, m;
int pre[maxn], mid[maxn];
int ans[maxn];
void build(int l, int r, int rt, int p){
if(l > r) return;
int pos = l;
while(pos <= r && mid[pos] != pre[rt]) ++pos;
ans[p] = pre[rt];
build(l , pos - 1, rt + 1, p << 1 | 1);// 递归左子树,传右节点参数
build(pos + 1, r, rt + (pos - l + 1), p << 1);// 递归右子树,传左节点参数
}
void work()
{
cin >> n;
for(int i = 1; i <= n; ++i) cin >> mid[i];
for(int i = 1; i <= n; ++i) cin >> pre[i];
build(1, n, 1, 1);
vector <int> v;
for(int i = 1; i <= n * 100; ++i) if(ans[i])
v.push_back(ans[i]);
for(int i = 0; i < v.size() - 1;++i) cout << v[i] << " ";
cout << v.back();
}
int main()
{
ios::sync_with_stdio(0);
// int TT;cin>>TT;while(TT--)
work();
return 0;
}
L2-035 完全二叉树的层序遍历 (25 分)
思路:
后序遍历的结果存到对应编号上即可
code:
#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
#define ull unsigned long long
#define ld long double
#define all(x) x.begin(), x.end()
#define mem(x, d) memset(x, d, sizeof(x))
#define eps 1e-6
using namespace std;
const int maxn = 2e3 + 9;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
ll n, m;
int last[maxn];
int ans[maxn], cnt;
void dfs(int x){
if(x > n) return;
dfs(x << 1);
dfs(x << 1 | 1);
ans[x] = last[++cnt];
}
void work()
{
cin >> n;
for(int i = 1; i <= n; ++i) cin >> last[i];
dfs(1);
for(int i = 1; i <= n; ++i) cout << ans[i] << " \n"[i==n];
}
int main()
{
ios::sync_with_stdio(0);
// int TT;cin>>TT;while(TT--)
work();
return 0;
}