二叉树和树的验证
用递归的方法实现以下算法:
1.以二叉链表表示二叉树,建立一棵二叉树;
2.输出二叉树的中序遍历结果;
3.输出二叉树的前序遍历结果;
4.输出二叉树的后序遍历结果;
10.设计二叉树的双序遍历算法(双序遍历是指对于二叉树的每一个结点来说,先访问这个结点,再按双序遍历它的左子树,然后再一次访问这个结点,接下来按双序遍历它的右子树)。
树结构定义
typedef struct BiNode
{
char data;
struct BiNode *lchild,*rchild;
}*BiTree,BiNode;
1.用先序遍历的方法创建一个二叉树
void Create(BiTree &T)//先序遍历创建一个二叉树
{
char ch;
cout << ">:";
cin>>ch;
if(ch=='#') //当遇到#字符时将树置空
{
T=NULL;
}
else
{
T=new BiNode;
T->data=ch;
Create(T->lchild);
Create(T->rchild);
}
}
2.先中后序遍历输出(递归写法)
void Lorder_Trave(BiTree &T)//先遍历一个二叉树
{
if(T)
{
cout<<T->data;
Lorder_Trave(T->lchild);
Lorder_Trave(T->rchild);
}
}
void Border_Trave(BiTree &T)//中遍历一个二叉树
{
if(T)
{
Border_Trave(T->lchild);
cout<<T->data;
Border_Trave(T->rchild);
}
}
void Rorder_Trave(BiTree &T)//后遍历一个二叉树
{
if(T)
{
Rorder_Trave(T->lchild);
Rorder_Trave(T->rchild);
cout<<T->data;
}
}
void B_order_Trave(BiTree &T)
{//中序遍历非递归
stack<BiNode*> S;
BiNode*p = new BiNode;
p = T;
BiNode* q = new BiNode;
while(p||!S.empty())
{
if(p)
{
S.push(p);
p = p->lchild;
}
else
{
q = S.top();
cout<<q->data;
S.pop();
p = q->rchild;
}
}
}
void L_Order_Trave(BiTree &T)
{//先序遍历非递归
BiNode* p = new BiNode;
BiNode* q = new BiNode;
p = T;
stack<BiNode*> S;
while(p||!S.empty())
{
if(p)
{
cout<<p->data;
S.push(p);
q = p;
p = p->lchild;
}
else
{
p = S.top();
S.pop();
p = p->rchild;
}
}
}
void R_Oreder_Trave(BiTree &T)
{//双栈后序遍历非递归(借助辅助栈的方式)
BiNode *q = new BiNode;
stack<BiNode*> S,output;
S.push(T);
while(!S.empty())
{
q = S.top();
output.push(q);
S.pop();
if(q->lchild)
S.push(q->lchild);
if(q->rchild)
S.push(q->rchild);
}
while(!output.empty())
{
cout<<output.top()->data;
output.pop();
}
}
void R_Order_Trave(BiTree &T)
{//运用单栈的方法进行后序非递归遍历
BiNode *p= new BiNoed;
BiNode* q = p;
BiNode *r = p;
p = T;
stack<BiNode*>S;
while(p||!S.empty())
{
if(p)
{
S.push(p);
p = p->lchild;
}
else
{
q = S.top();
if(q->rchild==NULL)
{
cout<<q->data;
r = S.top();
S.pop();
}
else if(q->rchild==r)
{
cout<<q->data;
r = S.top();
S.pop();
}
else
{
p = q->rchild;
}
}
}
3.计算一棵树的深度
int Depth(BiTree &T)//输出一个树的深度
{//当左子树为空时遍历其右子树,如果右子树为空,则返回两者之间最大的数
if(T==NULL)
return 0;
else /*当树不为空时,先遍历其左子树,当左子树不为空则继续遍历其左子树的左子树
若左子树为空,则遍历其右子树*/
{
int m,n;
m=Depth(T->lchild);
n=Depth(T->rchild);
if(m>n)
return m+1;
else
return n+1;
}
}
4.统计二叉树节点的个数
int NodeCount(BiTree &T)
{//先序遍历,最后加上根节点
if(!T)
return 0;
else
return NodeCount(T->lchild)+NodeCount(T->rchild)+1;/*先统计其左子树后返回统计其右子树,
两者相加后加一是整个树的节点个数*/
}
5.统计二叉树叶子节点的个数
void Yecount(BiTree &T,int &count)
{//当节点的左子树和右子树都为空时count++
if(T)
{
{if(T->lchild==NULL&&T->rchild==NULL)
count++;
Yecount(T->lchild,count);
Yecount(T->rchild,count);
}
}
}
6.统计度为1的节点的个数
int Nodeone(BiTree &T)
{//若左子树和右子树中仅有一个为空,则遍历其左子树或右子树的子树如果他们的子树为空,则返回1,返回上一层递归
if(!T)
return 0;
if((T->lchild!=NULL&&T->rchild==NULL)||(T->rchild!=NULL&&T->lchild==NULL))
return 1+Nodeone(T->lchild)+Nodeone(T->rchild);
return Nodeone(T->lchild)+Nodeone(T->rchild);
}
7.输出叶子节点到根节点的路径
void Path(BiTree &T,char *c,int len)
{//不为空的节点都存入数组,为空后从数组的最后一个数据开始输出,然后返回上一层递归,继续存入数组,然后输出
if(T)
{
if(T->lchild == NULL &&T->rchild == NULL)
{
cout<<T->data<<"-->";
for (int i = len-1; i>0;i --)
{
cout<<c[i]<<"-->";
}
cout<<c[0]<<endl;
}
else
{
c[len++]=T->data;
Path(T->lchild,c,len);//访问右子树时,前面共有的节点不会被重新赋值,只有后面不共有的才会被重新赋值
Path(T->rchild,c,len);
}
}
}
8.双序遍历
void DoubleTreave(BiTree &T)
{//创建一个节点用来存储父类节点,左子树访问完后输出父类节点后输出右子树
if(T)
{
BiTree newTree;
cout<<T->data;
newTree=T;
DoubleTreave(T->lchild);
cout<<newTree->data;
DoubleTreave(T->rchild);
}
}
9.输出最长的路径
void Longest_path(BiTree &T,BiTree* &longpath,int &longest)
{//使用非递归后序遍历的方法,将每个节点存入辅助数组path中,如果len大于longest长度将辅助数组的值赋值给longest数组
BiNode *p = T;
BiNode *q = new BiNode;
BiNode *r = new BiNode;
BiNode **path = new BiNode*[20];//创建一个每个元素都是一个节点指针类型的数组
int len = 0;
while(p||len>0)
{
if(p)
{
path[len++] = p;
p = p->lchild;
}
else
{
q = path[len-1];//取得数组最顶端元素
if(q->rchild==NULL||q->rchild==r)
{
r = q;
len--;//将数组长度减一
}
else
p = q->rchild;
}
if(len>longest)
{//将辅助数组赋值给目标数组
for(int i=0;i<len;i++)
{
longpath[i] = path[i];
}
longest = len;
}
}
}
先序插入的顺序为ABC##DE###F#G##
输出结果