// tree_li.cpp : 定义控制台应用程序的入口点。
//程序共能有:
//递归与非递归:创建树,先序、中序、后续遍历二叉树,求某一结点的所有祖先
//VC60下调试通过!
//
#include "stdafx.h"
# include <stdio.h>
# include <malloc.h>
#include <stack>
using std::stack;
# define ERROR -1
# define OK 1
//--------以下用户按照具体问题设定--------------------
typedef char TElemType; //指定char为二叉树结点元素类型
void visit (char e)
{ printf ("---%c---/n",e); }
//----------------------------------------------------
//-----------以下实现二叉树二叉链表的几个基本操作------------
typedef struct BiTNode {
TElemType data;
struct BiTNode *lchild,*rchild;
}BiTNode, *BiTree;
void CreateBiTree(BiTree &T)
{ char ch;
scanf ("%c",&ch);
if (ch=='#') T=NULL;
else {
T=new BiTNode;
T->data=ch;
CreateBiTree(T->lchild);
CreateBiTree(T->rchild);
};
}
void CountLeaf1 (BiTree T,int & count)
{ if (T) {
if ((!T->lchild)&&(!T->rchild)) count++;
CountLeaf1 (T->lchild,count);
CountLeaf1 (T->rchild,count);
};
}
int CountLeaf2 (BiTree T)
{
if (!T) return 0;
if ((!T->lchild)&&(!T->rchild)) return 1;
return CountLeaf2(T->lchild)+CountLeaf2(T->rchild);
}
void CountNode (BiTree T,int & count)
{
if (T!=NULL)
{
count++;
CountNode (T->lchild,count);
CountNode (T->rchild,count);
};
}
int CountDepth (BiTree T)
{
int templ,tempr;
if (!T) return 0;
else
{
templ=CountDepth(T->lchild);
tempr=CountDepth(T->rchild);
return (templ>=tempr)?templ+1:tempr+1;
};
}
int PreOrderTraverse (BiTree T, void (*visit)(TElemType e))
{ if (T) { visit (T->data);
PreOrderTraverse (T->lchild, visit);
PreOrderTraverse (T->rchild, visit);
};
return OK;
}
int InOrderTraverse (BiTree T, void (*visit)(TElemType e))
{ if (T) { InOrderTraverse (T->lchild, visit);
visit (T->data);
InOrderTraverse (T->rchild, visit);
};
return OK;
}
int PostOrderTraverse (BiTree T, void (*visit)(TElemType e))
{ if (T) { PostOrderTraverse (T->lchild, visit);
PostOrderTraverse (T->rchild, visit);
visit (T->data);
};
return OK;
}
void PreOrderTraverseEx(BiTree T,void (*visit)(TElemType e))
{
stack<BiTree> s;
BiTree p=T;
while(p!=NULL||!s.empty())
{
while(p!=NULL)
{
visit(p->data);
s.push(p);
p=p->lchild;
}
if(!s.empty())
{
p=s.top();
s.pop();
p=p->rchild;
}
}
}
void InOrderTraverseEx(BiTree T,void (*visit)(TElemType e))
{
stack<BiTree> s;
BiTree p=T;
while(p!=NULL||!s.empty())
{
while(p!=NULL)
{
s.push(p);
p=p->lchild;
}
if(!s.empty())
{
p=s.top();
visit(p->data);
s.pop();
p=p->rchild;
}
};
}
typedef enum{L,R}type;
typedef struct
{
BiTree ptr;
type tag;
}stacknode;
void PostOrderTraverseEx(BiTree T,void (*visit)(TElemType e))
{
stack<stacknode> s;
BiTree p=T;
stacknode tmp;
do
{
while(p!=NULL)
{
tmp.ptr=p;
tmp.tag=L;
s.push(tmp);
p=p->lchild;
}
while(!s.empty()&&s.top().tag==R)
{
tmp=s.top();
s.pop();
visit(tmp.ptr->data);
}
if(!s.empty())
{
s.top().tag=R;
p=s.top().ptr->rchild;
}
}while(!s.empty());
}
void TraverseAncestry(BiTree T,TElemType e,void (*visit)(TElemType e))
{
stack<TElemType> vs;
stack<stacknode> s;
BiTree p=T;
BiTree pre;
stacknode tmp;
do
{
while(p!=NULL)
{
tmp.ptr=p;
tmp.tag=L;
s.push(tmp);
p=p->lchild;
}
while(!s.empty()&&s.top().tag==R)
{
tmp=s.top();
s.pop();
if(tmp.ptr->data==e)
{
pre=tmp.ptr;
vs.push(e);
}
else if(tmp.ptr->lchild==pre||tmp.ptr->rchild==pre)
{
pre=tmp.ptr;
vs.push(pre->data);
}
// visit(tmp.ptr->data);
}
if(!s.empty())
{
s.top().tag=R;
p=s.top().ptr->rchild;
}
}while(!s.empty());
while(!vs.empty())
{
visit(vs.top());
vs.pop();
}
}
//-------------------------------------------------
//------------以下为调用基本操作的主函数-----------
int main()
{
BiTree T;
int count_Node,count_Leaf;
count_Node=0; count_Leaf=0;
printf ("请输入二叉树的先序遍历序列(包括空子树#符号)/n");
CreateBiTree (T);
printf ("二叉树建立完毕/n");
/* printf ("以下是先序遍历序列/n");
PreOrderTraverse (T,visit);
printf ("以下是中序遍历序列/n");
InOrderTraverse (T,visit);
printf ("以下是后序遍历序列/n");
PostOrderTraverse (T,visit);
printf ("以下计算节点数目/n");
CountNode (T,count_Node);
printf ("%d/n",count_Node);
printf ("以下计算叶子节点数目(方法1)/n");
CountLeaf1 (T,count_Leaf);
printf ("%d/n",count_Leaf);
printf ("以下计算叶子节点数目(方法2)/n");
printf ("%d/n",CountLeaf2(T));
printf ("以下计算二叉树的深度/n");
printf ("%d/n",CountDepth(T));
*/
printf ("以下是先序遍历序列/n");
PreOrderTraverseEx(T,visit);
printf ("以下是中序遍历序列/n");
InOrderTraverseEx(T,visit);
printf ("非递归后续遍历二叉树(二叉排序树)/n");
PostOrderTraverseEx(T,visit);
printf ("输出制定节点的所有祖先,采用非递归后续遍历二叉树(二叉排序树)/n");
TraverseAncestry(T,'b',visit);
return 0;
}