2015年数据结构第五题(输出二叉树的最长一枝)(C/C++)

题目:
在这里插入图片描述

代码实现:

#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回到它的上一个结点,寻找新的路。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值