题目:
代码实现:
#include<iostream>
using namespace std;
#define TElemType char
typedef struct BiTNode{
TElemType data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
void CreateBiTree(BiTree &T)//先序遍历的顺序建立二叉链表
{
TElemType ch;
cin>>ch;
if(ch=='#')T=NULL;
else
{
T=new BiTNode;
T->data=ch;
CreateBiTree(T->lchild);
CreateBiTree(T->rchild);
}
}
int Depth(BiTree &T)//递归计算二叉树的深度
{
int m,n;
if(T==NULL)return 0;
else
{
m=Depth(T->lchild);
n=Depth(T->rchild);
if(m>n)return (m+1);
else return (n+1);
}
}
//顺序栈及其基本操作........................................
#define MAXSIZE 50
#define SElemType BiTNode*
typedef struct
{
SElemType *base;
SElemType *top;
int stacksize;
}SqStack;
bool InitStack(SqStack &S)//初始化顺序栈
{
S.base=new SElemType[MAXSIZE];
if(!S.base)exit(EOVERFLOW);
S.top=S.base;
S.stacksize=MAXSIZE;
return true;
}
bool Push(SqStack &S,SElemType e)//入栈
{
if(S.top-S.base==S.stacksize)return false;
*S.top++=e;
return true;
}
bool Pop(SqStack &S,SElemType &e)//出栈
{
if(S.top==S.base)return false;
e=*--S.top;
return true;
}
SElemType GetTop(SqStack &S) //取栈顶元素
{
if(S.top!=S.base)return *(S.top-1);
}
void ShowStack(SqStack &S)//打印输出二叉树最长的一枝
{
printf("\n二叉树最长的那一枝:\n");
for(SElemType *p=S.base;p!=S.top;p++)
{
printf("%c ",(*p)->data);
}
printf("\n");
}
void Destroy(SqStack &S)//销毁栈
{
delete S.base;
S.base=NULL;
S.top=NULL;
}
int StackLength(SqStack &S)//统计栈内元素个数
{
return (S.top-S.base);
}
bool IsEmpty(SqStack S)//判断栈空
{
return (S.top==S.base);
}
//..........................................................
//本题解答..................................................
bool Judge(BiTNode* visited[],BiTNode* p)
{
for(int i=0;i<MAXSIZE;i++)
if(visited[i]==p)return true;
return false;
}
void Output_longest(BiTree &T)
{
SElemType e=NULL;
int i=0;
SqStack S;//用于存放当前正在被遍历的一枝
InitStack(S);
BiTNode* visited[MAXSIZE];
for(int i=0;i<MAXSIZE;i++)visited[i]=NULL;
BiTNode* p=T;
Push(S,p);
visited[i++]=p;
while(!IsEmpty(S))
{
while((GetTop(S))->lchild)
{
if(Judge(visited,(GetTop(S))->lchild))break;//判断当前指针p所在结点的左孩子是否被访问过
p=(GetTop(S))->lchild;
Push(S,p);visited[i++]=p;
}
while((GetTop(S))->rchild)
{
if(Judge(visited,(GetTop(S))->rchild))break;//判断当前指针p所在结点的右孩子是否被访问过
p=(GetTop(S))->rchild;
Push(S,p);visited[i++]=p;
}
if(StackLength(S)==Depth(T)) //判断栈内元素个数是否与树的深度一致
ShowStack(S); //打印输出二叉树最长的一枝
if(Judge(visited,(GetTop(S))->lchild)&&Judge(visited,(GetTop(S))->rchild))
Pop(S,e); //回退到上一个被访问的结点,如果栈顶结点的左右孩子全部被访问了
}
Destroy(S); //销毁栈
}
//..........................................................
void DestroyTree(BiTree &T)//销毁二叉树
{
if(T!=NULL)
{
DestroyTree(T->lchild);
DestroyTree(T->rchild);
printf("销毁结点: %c\n",T->data);
delete T;
T=NULL;
}
return;
}
int main()
{
BiTree T=NULL;
printf("先序建立二叉树:\n");
CreateBiTree(T);
Output_longest(T); //输出二叉树中的最长一枝(本题解答)
DestroyTree(T);//销毁二叉树
printf("\n成功销毁二叉树!\n");
return 0;
}
算法思想:设置顺序栈和visited数组,分别用来存当前正在访问的那一枝和已访问过的结点,设置指针p从树的根结点开始移动,每移动到一个新的结点,就把这个结点的地址放入栈中并存入visited数组,如果这个新结点为叶子结点,则栈就将其地址弹出,指针p回到它的上一个结点,寻找新的路。