题目链接:http://pat.zju.edu.cn/contests/pat-a-practise/1064
主要思想:将输入序列排序,然后通过完全二叉树的性质找出根节点,并存入相应位置中,然后递归找左右子树的根节点。最后输出即可!
1 #include<iostream> 2 #include<vector> 3 #include<algorithm> 4 #include<cmath> 5 using namespace std; 6 7 int level(int sum) 8 { 9 int n(0); 10 while(sum != 1) 11 { 12 sum /= 2; 13 ++n; 14 } 15 return n; 16 } 17 18 void builttree(int i, int j, vector<int> &v, vector<int> &tree, int pos) 19 { 20 if(i > j) 21 return; 22 if( i == j) 23 tree[pos] = v[i]; 24 else 25 { 26 /*共有多少节点i,j为下标*/ 27 int sum = j-i+1; 28 /*层数*/ 29 int levels = level(sum); 30 /*最后一层缺的节点数*/ 31 int absent = pow(2, (double)levels+1)-1 - sum; 32 /*最后一层剩的节点数*/ 33 int rest = pow(2, (double)levels) - absent; 34 /*左右子树节点数*/ 35 int lcn = (sum-rest)/2+(rest > pow(2, (double)levels-1) ? pow(2, (double)levels-1) : rest); 36 int rcn = sum - lcn-1; 37 /*将根存入对应位置*/ 38 tree[pos]=v[i+lcn]; 39 /*递归*/ 40 builttree(i, i+lcn-1, v, tree, 2*pos); 41 builttree(j-rcn+1, j, v, tree, 2*pos+1); 42 } 43 } 44 45 int main() 46 { 47 int num; 48 while(cin>>num) 49 { 50 vector<int> v(num); 51 for(int i=0; i<num; ++i) 52 cin>>v[i]; 53 sort(v.begin(), v.end()); 54 vector<int> tree(num+1); 55 builttree(0, v.size()-1, v, tree, 1); 56 for(int i=1; i<tree.size()-1; ++i) 57 cout<<tree[i]<<" "; 58 cout<<tree[tree.size()-1]<<endl; 59 } 60 return 0; 61 }