好久前就学完二叉树了,不过不善总结,到现在才温习一遍,感觉全是模板啊,有点难的就是那个树的同构~。
首先我们可以根据给出的字串建立起二叉树(如","为空节点特判),我们还可以根据(先序+中序)或者 (中序+后序)得到唯一的二叉树,当然了(先序+后序)得到可能的二叉树种数也是题目,不过我还没遇到,这里就不写了。建立好二叉树后我们可以先序(根左右),中序(左根右),后序(左右根),层序,来遍历二叉树,层次遍历我们用队列来实现即可,层次遍历中遇到的叶子节点特判输出即可(如果这是题目的话),获得叶子节点的数目的话,找左右全为空的节点++即可。
#include<bits/stdc++.h>
using namespace std;
struct node
{
node *l,*r;
char data;
};
char a[100];
int top=-1,sum;
node *create1()
{
node *root;
root=new node;
top++;
if(a[top]==',') //","代表空节点
return NULL;
else //树根节点,左右子树的建立
{
root->data=a[top];
root->l=create1();
root->r=create1();
}
return root; //return 的是一个树
}
node *create2(char *previous,char *middle,int len)//先序+中序==二叉树
{
if(len<=0)
return NULL; //终止条件很重要
node *root;
root=new node;
root->data=previous[0];
int i;
for(i=0;i<len;i++)
{
if(middle[i]==previous[0])//找到中序遍历中根节点的分界
break;
}
root->l=create2(previous+1,middle,i);//画个图很好理解
root->r=create2(previous+i+1,middle+i+1,len-1-i);
return root;
}
node *create3(char *middle,char *finall,int len)//中序+后序==二叉树
{
if(len<=0)
return NULL;
node *root;
root=new node;
root->data=finall[len-1];
int i;
for(i=0;i<len;i++)
{
if(middle[i]==finall[len-1])
break;
}
root->l=create3(middle,finall,i);
root->r=create3(middle+i+1,finall+i,len-1-i);
return root;
}
void previousshow(node *root) //先序根左右
{
if(root)
{
cout<<root->data;
previousshow(root->l);
previousshow(root->r);
}
}
void middleshow(node *root)//中序左根右
{
if(root)
{
middleshow(root->l);
cout<<root->data;
middleshow(root->r);
}
}
void finallshow(node *root) //后序左右根
{
if(root)
{
finallshow(root->l);
finallshow(root->r);
cout<<root->data;
}
}
void layershow(node *root) //运用队列实现的层次遍历
{
queue<node*>que;//注意这里是node*,坑死我了
if(root) //一定要特判,不然会RE
{
que.push(root);
cout<<que.front()->data;
}
while(que.size())
{
node *root=que.front(); //常用手段
que.pop();
if(root->l) //依次找左右儿子输出即可
{
cout<<root->l->data;
que.push(root->l);
}
if(root->r)
{
cout<<root->r->data;
que.push(root->r);
}
}
}
void layershow(node *root) //运用层次遍历输出叶子节点
{
queue<node*>que;//注意这里是node*,坑死我了
if(root) //一定要特判,不然会RE
{
que.push(root);
}
while(que.size())
{
node *root=que.front(); //常用手段
if(root->l==NULL&&root->r==NULL) //输出叶子节点
cout<<root->data;
que.pop();
if(root->l) //依次找左右儿子输出即可
{
que.push(root->l);
}
if(root->r)
{
que.push(root->r);
}
}
}
int getdepth(node *root) //求深度和高度,不过其还是有点差别的
{
int depth=0;
if(root)
depth=max(getdepth(root->l),getdepth(root->r))+1;
return depth;
}
int getleafsum(node *root) //获得叶子节点的个数
{
if(root)
{
if(root->l==NULL&&root->r==NULL) //左右全为空的节点为叶子节点
sum++;
else
{
getleafsum(root->l);//遍历树
getleafsum(root->r);
}
}
return sum;
}