二叉树,递归、非递归遍历,求深度,输出叶子节点

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <malloc.h>
#define ElemType char//元素类型

#define STACK_INIT_SIZE 100
#define _br_ printf("\n")
typedef char TElemType;

/*
* \param 二叉树
* \author Silent_Amour
*/

typedef struct BiTNode {
   ElemType data;
   struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;

typedef struct {
   BiTree *base;
   BiTree *top;
   int Size;
} Stack;

int initStack(Stack &S)
{
   S.base = (BiTree *)malloc(STACK_INIT_SIZE*sizeof(BiTree));
   if (!S.base)exit(-1);
   S.top = S.base;
   S.Size = STACK_INIT_SIZE;
   return 1;
}

int StackPop(Stack &S, BiTree &e)
{
   if (!S.top || S.top == S.base)
      return -1;
   e = *--S.top;

// printf("出栈%d,%d\n", S.top, e);
   return 1;
}

int StackPush(Stack &S, BiTree e)
{
   if (S.top-S.base>= S.Size)
      exit(-1);

   *S.top++ = e;
// printf("进栈%d,地址:%d\n", S.top, e);
   return 1;
}

int DisplayElem(TElemType e)
{
   printf("%c ", e);
   return 1;
}

int creatBiTree(BiTree &T)
{
   char ch;
   ch=getchar();
   if (ch == '.')
      T = NULL;
   else

   {
      if (!(T = (BiTNode *)malloc(sizeof(BiTNode))))
         exit(-1);
      T->data = ch;
      creatBiTree(T->lchild);
      creatBiTree(T->rchild);
   }
   return 1;
}

int PreOrderTraverse(BiTree T, int(*DisplayElem)(TElemType e))
{
   if (T) {
      if (DisplayElem(T->data))
         if (PreOrderTraverse(T->lchild, DisplayElem))
            if (PreOrderTraverse(T->rchild, DisplayElem))
               return 1;
      return -1;
   } else
      return 1;

}

int InOrderTraverse(BiTree T, int(*DisplayElem)(TElemType e))
{
   if (T) {
      if (InOrderTraverse(T->lchild, DisplayElem))
         if (DisplayElem(T->data))
            if (InOrderTraverse(T->rchild, DisplayElem))
               return 1;
      return -1;
   } else return 1;
}

int PostOrderTraverse(BiTree T, int(*DisplayElem)(TElemType e))
{
   if (T) {
      if (PostOrderTraverse(T->lchild, DisplayElem))
         if (PostOrderTraverse(T->rchild, DisplayElem))
            if (DisplayElem(T->data))
               return 1;
      return -1;
   } else return 1;
}

int InOrderTraverse_Stack(BiTree T, int(*DisplayElem)(TElemType e))
{
   BiTree p = T;
   BiTree s[100];
   int top=-1;
   while (p||top!=-1) {
      while (p) {
         s[++top]=p;
         p = p->lchild;
      }
      if(top!=-1) {
         p=s[top--];
         if (!DisplayElem(p->data))return -1;
         p = p->rchild;
      }
   }
   return 1;
}


void InOrderUnrec(BiTree t)
{
   Stack s;
   initStack(s);
   BiTree p=t;
   while (p!=NULL || s.top!=s.base) {
      while (p!=NULL) {
         StackPush(s,p);
         p=p->lchild;
      }

      if (s.top!=s.base) {
         StackPop(s,p);
         DisplayElem(p->data);
         p=p->rchild;
      }
   }
}

void PreOrderUnrec(BiTree t)
{
   Stack s;
   initStack(s);
   BiTree p=t;
   while (p!=NULL || s.top!=s.base) {
      while (p!=NULL) {
         DisplayElem(p->data);
         StackPush(s,p);
         p=p->lchild;
      }

      if (s.top!=s.base) {
         //访问根结点
         StackPop(s,p);
         p=p->rchild;
      }
   }
}


int Depth(BiTree t)
{
   int ld=0,rd=0;
   BiTree s=t;
   if(!t)
      return 0;
   if(t) {
      ld=Depth(s->lchild);
      rd=Depth(s->rchild);
   }
   if(ld>=rd)
      return ld+1;
   return rd+1;
}

void disp_leaf(BiTree t)
{
	BiTNode *p=t;
	if(p)
	{
		
	if(p->lchild==NULL&&p->rchild==NULL)
		printf("%c ",p->data);
		disp_leaf(p->lchild);
		disp_leaf(p->rchild);
	}
}


int main()
{
   BiTree S;
   creatBiTree(S);
   printf("递归先序遍历:\n");
   PreOrderTraverse(S, DisplayElem);
   _br_;
   printf("递归中序遍历:\n");
   InOrderTraverse(S, DisplayElem);
   _br_;
   printf("递归后序遍历:\n");
   PostOrderTraverse(S, DisplayElem);
   _br_;
   printf("非递归中序遍历(小堆栈):\n");
   InOrderTraverse_Stack(S, DisplayElem);
   _br_;
   printf("非递归中序遍历(标准堆栈):\n");
   InOrderUnrec(S);
   _br_;
   printf("非递归先序遍历(标准堆栈):\n");
   PreOrderUnrec(S);
   _br_;
   printf("深度:%d",Depth(S));
   _br_;
   printf("所有的叶子节点为:\n");
   disp_leaf(S);
   free(S);
   return 0;
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
二叉树是一种常见的数据结构,包含根节点、左子树和右子树。在进行二叉树遍历时,我们需要按照某种顺序访问二叉树中的每个节点,包括先序遍历、中序遍历和后序遍历。为了实现这些遍历方式,我们可以使用递归非递归两种方式。 一、递归遍历 递归遍历是一种简单直观的遍历方式,也是最常用的一种方式。以先序遍历为例,递归遍历的具体实现如下: 1. 如果当前节点不为空,则输出当前节点的值 2. 如果当前节点有左子树,则递归遍历左子树 3. 如果当前节点有右子树,则递归遍历右子树 中序遍历和后序遍历的实现类似,只需要改变输出节点值的位置即可。 递归遍历的优点是实现简单,代码清晰易懂,但是当二叉树深度很大时,递归调用会导致系统栈溢出,从而影响程序的性能。因此,对于深度较大的二叉树,我们需要使用非递归遍历来实现。 二、非递归遍历 非递归遍历是利用栈来实现的。以先序遍历为例,非递归遍历的具体实现如下: 1. 将根节点入栈 2. 当栈不为空时,取出栈顶元素,输出其值 3. 如果栈顶元素有右子树,则将其右子树入栈 4. 如果栈顶元素有左子树,则将其左子树入栈 5. 重复步骤2-4,直到栈为空 中序遍历和后序遍历的实现类似,只需要改变入栈顺序即可。 非递归遍历的优点是可以避免递归调用导致的系统栈溢出问题,同时也可以提高程序的运行效率。但是需要注意的是,由于使用了栈来存储节点,因此需要额外的存储空间。 总结: 递归遍历非递归遍历都是二叉树遍历的常用方式。递归遍历简单易懂,但对于深度较大的二叉树可能会导致系统栈溢出。非递归遍历需要使用栈来存储节点,可以避免递归调用导致的问题,但需要额外的存储空间。在实际应用中,我们需要根据实际情况选择合适的遍历方式来实现二叉树遍历
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值