PAT1064

题目链接: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 }

 

posted @ 2013-10-16 00:08  coding_monkey  阅读(167)  评论(0编辑  收藏  举报