题目链接:https://pintia.cn/problem-sets/994805342720868352/problems/994805407749357568
题目大意:给出n个数,让你建立一棵完全二叉树,并输出层序遍历的结果。
分析:先把给出的数组排序,再求出要建立的树有多少层。因为中序遍历的结果就是顺序的,所以按照中序递归,每递归一层,层数减一,求出当前根节点是第几个数,然后先往左子树走,再给当前根节点赋值,最后往右子树走。当只剩下一个节点或者层数为1时,赋值,返回。最后层序遍历一下就可以了。
数组开大点。。。
#include <bits/stdc++.h>
using namespace std;
const int N = 1e4 + 5;
int n, pos, a[N], ans[N], sum[N];
void init() {
sum[1] = 1;
for(int i = 2; i < 15; i++)
sum[i] = sum[i - 1] + pow(2, i - 1);
}
void dfs(int x, int cnt, int l, int r) {
if(l > r) return ;
if(l == r || cnt == 1) {
ans[x] = a[pos++];
return ;
}
int num = r - l + 1;
int rt = (sum[cnt - 1] - 1) / 2;
int cha = sum[cnt] - sum[cnt - 1];
rt += min(num - sum[cnt - 1], cha / 2);
rt++;
rt = rt + l - 1;
dfs(x<<1, cnt - 1, l, rt - 1);
ans[x] = a[rt];
pos++;
dfs(x<<1|1, cnt - 1, rt + 1, r);
}
void solve() {
queue<int> q;
q.push(1);
int d = 0;
while(!q.empty()) {
int tmp = q.front();
q.pop();
if(d > 0) printf(" ");
printf("%d", ans[tmp]);
d++;
if(ans[tmp<<1] != -1) q.push(tmp<<1);
if(ans[tmp<<1|1] != -1) q.push(tmp<<1|1);
}
printf("\n");
}
int main() {
init();
scanf("%d", &n);
for(int i = 1; i <= n; i++)
scanf("%d", &a[i]);
sort(a + 1, a + n + 1);
int cnt = 1;
while(n >= sum[cnt]) cnt++;
if(n - sum[cnt] == 0) cnt--;
pos = 1;
memset(ans, -1, sizeof ans);
dfs(1, cnt, 1, n);
solve();
return 0;
}
链表实现
#include <bits/stdc++.h>
using namespace std;
const int N = 1010;
int n, pos, a[N], ans[N], sum[N];
struct node {
int data;
node *left, *right;
};
struct node *root = NULL;
void init() {
sum[1] = 1;
for(int i = 2; i < 15; i++)
sum[i] = sum[i - 1] + pow(2, i - 1);
}
void dfs(node * &root, int cnt, int l, int r) {
if(l > r) return ;
if(l == r || cnt == 1) {
root = new node();
root->data = a[pos++];
root->left = root->right = NULL;
return ;
}
if(root == NULL) {
root = new node();
root->left = root->right = NULL;
}
int num = r - l + 1;
int rt = (sum[cnt - 1] - 1) / 2;
int cha = sum[cnt] - sum[cnt - 1];
rt += min(num - sum[cnt - 1], cha / 2);
rt++;
rt = rt + l - 1;
dfs(root->left, cnt - 1, l, rt - 1);
root->data = a[rt];
pos++;
dfs(root->right, cnt - 1, rt + 1, r);
}
void solve() {
queue<node*> q;
q.push(root);
int d = 0;
while(!q.empty()) {
node *tmp = q.front();
q.pop();
if(d > 0) printf(" ");
printf("%d", tmp->data);
d++;
if(tmp->left != NULL) q.push(tmp->left);
if(tmp->right != NULL) q.push(tmp->right);
}
printf("\n");
}
int main() {
init();
scanf("%d", &n);
for(int i = 1; i <= n; i++)
scanf("%d", &a[i]);
sort(a + 1, a + n + 1);
int cnt = 1;
while(n >= sum[cnt]) cnt++;
if(n - sum[cnt] == 0) cnt--;
pos = 1;
dfs(root, cnt, 1, n);
solve();
return 0;
}