用一个数组存储完全二叉树 若一个根节点索引为k,则其左子树索引为2k,右子树索引为2k+1;
见下一题 题目来自UVA679
# include<iostream>
# include<cstring>
using namespace std;
/*
input:树的深度 D , the number of balls:i
output:最后一个小球的位置;
节点为0,走左 且置1 ;
节点为1,走右 且置0;
*/
const int max_n=20;
int tree[1<<max_n];
int main()
{
int m;
int d,i;
cin>>m;
while(m--)
{
cin>>d;
if(d==-1) return 0;
cin>>i;
long long dd=(1<<d)-1;
memset(tree,0,sizeof(tree));
int w;
for(int j=0;j<i;j++)
{
w=0;
while(true)
{
if(tree[w]==0)
{
tree[w]=1;
w=2*w;
}
else
{
tree[w]=0;
w=2*w+1;
}
if(w>dd)
break;
}
}
cout<<w/2<<endl;
}
}
指针形式的二叉树
见下题uva122
# include<iostream>
# include<cstring>
# include<queue>
# include<vector>
using namespace std;
const int maxn=100000;
struct node{
int v;
bool have_value;
node*left,*right;
node()
{
have_value=false;
left=NULL;
right=NULL;
}
};
node *root;
vector<int> ans;
bool failed;
char s[maxn];
node* newnode()
{
return new node();
}
void addnode(int ,char*);
bool read_input()
{
failed=false;
root=newnode();
for(;;)
{
if(scanf("%s",s)!=1) return false;
if(!strcmp(s,"()")) break;
int v;
sscanf(&s[1],"%d",&v);
addnode(v,strchr(s,',')+1);
}
return true;
}
void addnode(int v,char*s)
{
int n=strlen(s);
node *u=root;
for(int i=0;i<n;i++)
{
if(s[i]=='L')
{
if(u->left==NULL) u->left=newnode();
u=u->left;
}
else if(s[i]=='R')
{
if(u->right==NULL) u->right=newnode();
u=u->right;
}
}
if(u->have_value) failed=true;
u->v=v;
u->have_value=true;
}
bool bfs(vector<int >&ans)
{
queue<node*> q;
ans.clear();
q.push(root);
while(!q.empty())
{
node *u=q.front();q.pop();
if(!u->have_value) return false;
ans.push_back(u->v);
if(u->left) q.push(u->left);
if(u->right) q.push(u->right);
}
return true;
}
int main()
{
read_input();
failed=bfs(ans);
if(!failed) {
cout<<"-1";
return 0;
}
for(vector<int> ::iterator in=ans.begin();in!=ans.end();++in)
{
cout<<*in<<" ";
}
return 0;
}
用两个数组存放二叉树
见uva548
根节点root l_tree[root]为左子树,r_tree[root]为右子树
# include<iostream>
# include<sstream>
# include<string>
using namespace std;
//通过中序 和后序 输出先序
const int max_n=100000;
int in_order[max_n];
int post_order[max_n];
int r_tree[max_n];
int l_tree[max_n];
int n;
bool readlist(int *a)
{
string line;
n=0; //即调用一次readlist()需赋值。因为不重复赋值n的值会一直加下去;
int x;
if(!getline(cin,line)) return false;
stringstream ss(line);
while(ss>>x) a[n++]=x;
return n>0;
}
int build(int l1,int r1,int l2,int r2)
{
if(l1>r1) return false;
int root=post_order[r2];
int p=l1;
while(in_order[p]!=root) p++;
int cnt=p-l1;
l_tree[root]=build(l1,p-1,l2,l2+cnt-1);
r_tree[root]=build(p+1,r1,l2+cnt,r2-1);
return root;
}
int best,best_sum;
void dfs(int u,int sum)
{
sum+=u;
if(!l_tree[u]&&!r_tree[u])
{
if(sum<best_sum||(sum==best_sum&&u<best))
{
best=u;
best_sum=sum;
}
}
if(l_tree[u]) dfs(l_tree[u],sum);
if(r_tree[u]) dfs(r_tree[u],sum);
}
void dfs(int u)
{
cout<<u<<" ";
if(l_tree[u]) dfs(l_tree[u]);
if(r_tree[u]) dfs(r_tree[u]);
}
int main()
{
readlist(in_order);
readlist(post_order);
build(0,n-1,0,n-1);
//dfs(post_order[n-1]);
best_sum=1000000;
dfs(post_order[n-1],0);
cout<<best;
return 0;
}
|