根据完全二叉树的性质进行一些计算即可。只是需要注意输出层序遍历得在struct中定义索引值变量,而不是表示层号的level变量,因为如果定义的是level变量,那么在sort的时候,同一层的排序可能被排错。
另外,这里由于它是一个完整树,可以直接将层序序列设为数组,长度为n即可。(只是因为是完整树的情况下,否则数组长度就很大了)
#include<iostream>
#include<vector>
#include<algorithm>
#include<cmath>
using namespace std;
struct node {
int key, i; //键,索引值
};
bool cmp(node a, node b) {
return a.i < b.i;
}
vector<int> a;
vector<node> level;
void getlevel(int left, int right, int index) {
if (left > right) {
return;
}
int num = right - left + 1;
int k = log(num + 1) / log(2.0); //完整的层数(即除了最后一层可能未满的层数)
int rest = num - (pow(2,k)-1); //最后一层的节点数
int restL = rest > pow(2, k - 1) ? pow(2, k - 1) : rest; //最后一层在左子树中的节点数
int numL = pow(2, k - 1) - 1 + restL; //左子树节点数
level.push_back({ a[left + numL],index });
getlevel(left, left+numL - 1,index*2+1);
getlevel(left+numL + 1, right, index*2+2);
}
int main() {
int n; cin >> n;
a.resize(n);
for (int i = 0; i < n; i++) {
cin >> a[i];
}
sort(a.begin(), a.end());
getlevel(0, n - 1, 0);
sort(level.begin(), level.end(), cmp);
for (int i = 0; i < n; i++) {
if (i == 0) cout << level[i].key;
else cout << " " << level[i].key;
}
return 0;
}