原题
点此链接1
基本分析
参考陈越姥姥的解题2,主要的难点在于在何处插入新元素使得满足完全搜索二叉树的条件。猜测还有一种更通用的动态插入算法。
代码
#include <iostream>
#include <queue>
#include <string>
#include <memory>
#include <algorithm>
using namespace std;
int sum;
vector<int> res;
int Father(int num)
{
if (num == 0)
return -1;
return num / 2;
}
int Left(int num)
{
auto v = 2 * num+1;
if ((sum - 1) >= v)
return v;
else
return -1;
}
int Right(int num)
{
auto v = 2 * num + 2;
if ((sum - 1) >= v)
return v;
else
return -1;
}
void Cal(const vector<int> &sets, int p)
{
if (sets.empty())
return;
if (sets.size() == 1)
{
res[p] = sets[0];
return;
}
// calculate how many elements of the left sub tree.
auto tmpSum = 1;
auto tmpH = 1;
while (tmpSum<sets.size())
{
tmpH *= 2;
tmpSum += tmpH;
}
int left;
tmpSum -= tmpH;
if ((tmpSum + tmpH / 2)>sets.size())
left = (tmpSum - 1) / 2 + sets.size() - tmpSum;
else
left = (tmpSum + tmpH - 1) / 2;
res[p] = (sets[left]);
if (Left(p) != -1)
Cal(vector<int>(sets.begin(), sets.begin() + left), 2 * p + 1);
if (Right(p) != -1)
Cal(vector<int>(sets.begin()+left+1, sets.end()), 2 * p + 2);
}
int main()
{
cin >> sum;
vector<int> sets;
for (auto i = 0; i < sum; i++)
{
int t;
cin >> t;
sets.push_back(t);
}
sort(sets.begin(), sets.end());
res.resize(sum);
Cal(sets, 0);
for (auto i = 0; i < sum;i++)
if (i == (sum - 1))
cout << res[i] << endl;
else
cout << res[i] << " ";
system("pause");
return 0;
}