实现二叉树的先序、中序、后序递归遍历和中序非递归遍历,并求叶子几点个数和高度,以菜单的方式输出。

首先,可以确定先序、中序和后序递归遍历,先建立二叉树进行遍历。

首先,先建立二叉树,进行先序、中序和后序递归遍历。

/**二叉树的建立--按照先序方式建立--插入**/
void CreateBiTree(BiTree &T)
{
    char val;//节点的数据类型 
    scanf("%c",&val);
 
    if(val == '#')
        T = NULL;  //null表示为空枝
    else
    {
        T = (BiTree)malloc(sizeof(BiTreeNode));
        T->data = val;
        CreateBiTree(T->left);//构造左子树 
        CreateBiTree(T->right);//构造右子树 
    }
}
 
 
/**先序遍历  根左右**/
void PreOrderTravel(BiTree T)
{
    if(T==NULL)
        return;
    printf("%c ",T->data);
    PreOrderTravel(T->left);
    PreOrderTravel(T->right);
}
 
/**中序遍历 左根右**/
void InOrderTravel(BiTree T)
{
    if(T==NULL)
        return;
    InOrderTravel(T->left);
    printf("%c ",T->data);
    InOrderTravel(T->right);
}
 
/**后序遍历 左右根**/
void TailOrderTravel(BiTree T)
{
    if(T==NULL)
        return;
    TailOrderTravel(T->left);
    TailOrderTravel(T->right);
    printf("%c ",T->data);
}

接着,遍历中序非递归遍历,我们利用构建栈来实现,先实现栈的基本功能。

  /**构造一个空栈**/
Status InitStack(SqStack &S)
	{
		//1.申请空间
		S.base =(BiTree*)malloc(STACK_INIT_SIZE * sizeof(BiTree));
		if(!S.base)  exit(0);//储存空间分配失败 
		S.top=S.base;  //栈底和栈顶指针指向同一块内存 
		S.stacksize= STACK_INIT_SIZE;
		return OK;
	}

/**插入元素e为新的栈顶元素(入栈操作)**/
Status Push(SqStack &S,BiTree e)
{
	//满不满,若满追加存储空间 
	if(S.top-S.base==S.stacksize)
	{
		//重新初始化
		S.base=(BiTree*)realloc(S.base,(S.stacksize + STACKINCREMENT)* sizeof(BiTree));
		if(!S.base)  exit(0);
		S.top=S.base+ S.stacksize;
		S.stacksize += STACKINCREMENT;
	}
	//元素e入栈
	*S.top=e;
	S.top++;//栈顶指针指向下一个 
	return OK;
}

/**若栈不空,则删除S的栈顶元素,用e为返回其值(出栈操作)**/
Status Pop(SqStack &S,BiTree &e)
{
	//1.判断
	if(S.top==S.base) return ERROR;
	S.top--;
	e=*S.top;
	return OK;
}

/**若栈S空,则返回1,若不空返回0(判空操作)**/
Status StackEmpty(SqStack S)
{
	//判断栈是否为空
	if(S.top==S.base) 
	 return 1;
	else;
	return 0;
}

进行中序非递归遍历。

/**中序遍历非递归**/
void InOrderTravel_n(BiTree T)
 {
 	SqStack S;
 	InitStack(S);
 	BiTreeNode *p=T;
 	while(p||!StackEmpty(S)){
 		if(p){
 			Push(S,p);
 			p=p->left;
		 }
		 else{
		     Pop(S,p);
		 	printf("%c ",p->data);
			 
		 	p=p->right;
		 }
	 }
	 return ;
 	
 }

统计二叉树叶子节点和高度。


/* 计算度为0的结点*/
void CountNode0(BiTree T)
{
	
    if(T==NULL)
    return ;
    CountNode0(T->left);
    CountNode0(T->right);
	if(T->left==NULL&&T->right==NULL)
	    count0++;
	
 } 
 
 /*求二叉树高度*/
 int height(BiTree T)  
{ 
   int L,R;
    if(T==NULL)
       return 0;
     L= height(T->left);
     R=height(T->right);
     return L>R ?(L +1) :(R +1);

	       
}  

完整代码:

#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 100
#define OK 1
#define ERROR 0
#define STACK_INIT_SIZE 100//存储空间初始分配量
#define STACKINCREMENT 10//存储空间分配增量

typedef  int Status;//函数返回值状态
int count0=0;
/**二叉树数据结构定义**/
typedef struct BiTreeNode
{
    char data;
    struct BiTreeNode *left;
    struct BiTreeNode *right;
}BiTreeNode,*BiTree;

/*********************************************栈的操作部分************************************/ 
 /**栈的顺序结构定义**/
 typedef struct stack
{
	BiTree*base;//栈底指针
	BiTree*top;//栈顶指针
	int stacksize;//当前栈空间的最大容量
}SqStack;//顺序栈

//基本操作(函数声明部分)
Status InitStack(SqStack &S);  //构造一个空栈
Status Push(SqStack &S,BiTree e);//入栈操作
Status Pop(SqStack &S,BiTree &e);//出栈操作
Status StackEmpty(SqStack S);//判断栈是否为空
void CreateBiTree(BiTree &T);//二叉树的初始化 
void PreOrderTravel(BiTree T);//先序递归遍历
void InOrderTravel(BiTree T);//中序递归遍历
void TailOrderTravel(BiTree T);//后序递归遍历
void InOrderTravel_n(BiTree T);//中序非递归遍历
void CountNode0(BiTree T);//计算度为0的结点
int height(BiTree T)  ;//求二叉树高度
void Menu();//显示菜单信息




  /**构造一个空栈**/
Status InitStack(SqStack &S)
	{
		//1.申请空间
		S.base =(BiTree*)malloc(STACK_INIT_SIZE * sizeof(BiTree));
		if(!S.base)  exit(0);//储存空间分配失败 
		S.top=S.base;  //栈底和栈顶指针指向同一块内存 
		S.stacksize= STACK_INIT_SIZE;
		return OK;
	}

/**插入元素e为新的栈顶元素(入栈操作)**/
Status Push(SqStack &S,BiTree e)
{
	//满不满,若满追加存储空间 
	if(S.top-S.base==S.stacksize)
	{
		//重新初始化
		S.base=(BiTree*)realloc(S.base,(S.stacksize + STACKINCREMENT)* sizeof(BiTree));
		if(!S.base)  exit(0);
		S.top=S.base+ S.stacksize;
		S.stacksize += STACKINCREMENT;
	}
	//元素e入栈
	*S.top=e;
	S.top++;//栈顶指针指向下一个 
	return OK;
}

/**若栈不空,则删除S的栈顶元素,用e为返回其值(出栈操作)**/
Status Pop(SqStack &S,BiTree &e)
{
	//1.判断
	if(S.top==S.base) return ERROR;
	S.top--;
	e=*S.top;
	return OK;
}

/**若栈S空,则返回1,若不空返回0(判空操作)**/
Status StackEmpty(SqStack S)
{
	//判断栈是否为空
	if(S.top==S.base) 
	 return 1;
	else;
	return 0;
}
/*********************************************二叉树的操作部分************************************/ 


/**二叉树的建立--按照先序方式建立--插入**/
void CreateBiTree(BiTree &T)
{
    char val;//节点的数据类型 
    scanf("%c",&val);
 
    if(val == '#')
        T = NULL;  //null表示为空枝
    else
    {
        T = (BiTree)malloc(sizeof(BiTreeNode));
        T->data = val;
        CreateBiTree(T->left);//构造左子树 
        CreateBiTree(T->right);//构造右子树 
    }
}
 
 
/**先序遍历  根左右**/
void PreOrderTravel(BiTree T)
{
    if(T==NULL)
        return;
    printf("%c ",T->data);
    PreOrderTravel(T->left);
    PreOrderTravel(T->right);
}
 
/**中序遍历 左根右**/
void InOrderTravel(BiTree T)
{
    if(T==NULL)
        return;
    InOrderTravel(T->left);
    printf("%c ",T->data);
    InOrderTravel(T->right);
}
 
/**后序遍历 左右根**/
void TailOrderTravel(BiTree T)
{
    if(T==NULL)
        return;
    TailOrderTravel(T->left);
    TailOrderTravel(T->right);
    printf("%c ",T->data);
}

/**中序遍历非递归**/
void InOrderTravel_n(BiTree T)
 {
 	SqStack S;
 	InitStack(S);
 	BiTreeNode *p=T;
 	while(p||!StackEmpty(S)){
 		if(p){
 			Push(S,p);
 			p=p->left;
		 }
		 else{
		     Pop(S,p);
		 	printf("%c ",p->data);
			 
		 	p=p->right;
		 }
	 }
	 return ;
 	
 }


/* 计算度为0的结点*/
void CountNode0(BiTree T)
{
	
    if(T==NULL)
    return ;
    CountNode0(T->left);
    CountNode0(T->right);
	if(T->left==NULL&&T->right==NULL)
	    count0++;
	
 } 
 
 /*求二叉树高度*/
 int height(BiTree T)  
{ 
   int L,R;
    if(T==NULL)
       return 0;
     L= height(T->left);
     R=height(T->right);
     return L>R ?(L +1) :(R +1);

	       
}  
/*打印二叉树操作菜单 */ 
void Menu( )
{
	printf("-----------1:先序遍历二叉树-----------------------------------\n");
	printf("-----------2:中序遍历二叉树-----------------------------------\n");
	printf("-----------3:后序遍历二叉树-----------------------------------\n");
	printf("-----------4:中序遍历二叉树(非递归算法)---------------------\n");
	printf("-----------5:统计二叉树中叶子个数-----------------------------\n");
	printf("-----------6:统计二叉树的高度---------------------------------\n");
	printf("-----------7:查看二叉树所有遍历、叶子个数和高度---------------\n");
	printf("-----------8:结束对二叉树的操作-------------------------------\n");
}
 
int main()
{
	int i;//选择
	 BiTree T;
    T = (BiTree)malloc(sizeof(BiTreeNode));
 
    printf("请给二叉树按照先序方式依次输入结点的值(空结点为#):\n");
    CreateBiTree(T);
 	//显示二叉树操作菜单
 	printf("===================================菜单=========================================\n");
 	while(1)
	{
			
				Menu();
				printf("请输入你的选择:");
				scanf("%d",&i);
				switch(i)
				{
				case 1:
					printf("先序方式遍历结果:\n");
					PreOrderTravel(T);
					printf("\n");
					break;
				case 2:
					printf("中序方式遍历结果:\n");
					InOrderTravel(T);
					printf("\n");
					break;
				case 3:
					printf("后序方式遍历结果:\n");
                    TailOrderTravel(T);
					printf("\n");
					break;
				case 4:
					printf("中序非递归遍历二叉树结果为:\n");
 	                InOrderTravel_n(T);
					printf("\n");
					break;
				case 5:
					CountNode0(T); 
                    printf("叶子节点共%d个\n",count0);
					count0=0; 
					printf("\n");
					break;
				case 6:
				    printf("二叉树的高度:%d\n",height(T));
				    break;
				case 7:
					printf("先序方式遍历结果:\n");
                    PreOrderTravel(T);
                    printf("\n");
                    printf("中序方式遍历结果:\n");
                    InOrderTravel(T);
                    printf("\n");
 
                    printf("后序方式遍历结果:\n");
                    TailOrderTravel(T);
                    printf("\n");
    
                    printf("中序非递归遍历二叉树结果为:\n");
                	InOrderTravel_n(T);
                    printf("\n");
      
                    printf("叶子结点结果:\n");
                    CountNode0(T); 
                    printf("共%d个\n",count0);
                    count0=0;
    
                    printf("二叉树的高度:%d\n",height(T));
                    printf("\n");
					break;
				case 8:exit(1);break;
				default:printf("请输入合法的选择值\n");
				}
		
	}
}

结果如图:

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值