将节点键值排序,然后确定根节点,每次求根节点左边节点数目,这样递归下去,然后用BFS层遍历。
#include <iostream>
#include <cstdio>
#include <queue>
#include <algorithm>
using namespace std;
int deep(int n){
if(n <= 1) return 0;
int h = 0;
while(true){
if(n > (1<<h)-1 && n <= (1<<(h+1))-1) break;
++h;
}
return h;
}
int leftSize(int n){
int h = deep(n);
if(h == 0) return 0;
int sum = (1<<h)-1;
if(n-sum <= (1<<(h-1))) return (sum-1)/2 + n-sum;
else return (sum-1)/2 + (1<<(h-1));
}
int main(){
int n;
cin >> n;
vector<int> keys(n);
for(int i = 0; i < n; ++i)
scanf("%d", &keys[i]);
sort(begin(keys), end(keys));
queue<pair<int,int>> Q;
Q.push({0, n});
vector<int> result;
while(!Q.empty()){
auto p = Q.front();
Q.pop();
int num = p.second-p.first;
if(num == 1) result.push_back(keys[p.first]);
else{
int left = leftSize(num);
int right = num-left-1;
result.push_back(keys[p.first+left]);
if(left) Q.push({p.first, p.first+left});
if(right) Q.push({p.first+left+1,p.second});
}
}
for(size_t i = 0; i < result.size(); ++i){
if(i) printf(" ");
printf("%d", result[i]);
}
return 0;
}