二叉树的深度(前序 中序 后序 递归非递归搜素)、广度、搜索 C++


a b c 使用 1 2 3 表示

/* 
描述:二叉树的深度(前序 中序 后序 递归非递归搜素)、广度、搜索
作者:jz
日期:20140819
*/
#include<stdio.h>
#include<malloc.h>
#include<process.h> /* exit() */
#include<iostream>
using namespace  std;
#include<stack>
#include<queue>

#define OK 1
#define  TElemType  int
#define Status int 
#define  Nil  (-1)
//结束符
#define TRUE  1
#define FALSE 0
#define ERROR 0

typedef struct BiTNode   /* 二叉树的二叉链表存储表示 */
{
	TElemType  data;
	struct BiTNode *lchild,*rchild; /* 左右孩子指针 */
}BiTNode,*BiTree;


enum enum_tag {L=1,R=2};//后序遍历使用作为标记
typedef struct StackNode
{//后序遍历使用
	enum_tag tag; 
	BiTNode* ptr;
}StackNode;

Status InitBiTree(BiTree *T)
{ /* 操作结果: 构造空二叉树T */
	*T=NULL;
	return OK;
}

void DestroyBiTree(BiTree *T)
{ /* 初始条件: 二叉树T存在。操作结果: 销毁二叉树T */
	if(*T) /* 非空树 */
	{
		if((*T)->lchild) /* 有左孩子 */
			DestroyBiTree(&(*T)->lchild); /* 销毁左孩子子树 */
		if((*T)->rchild) /* 有右孩子 */
			DestroyBiTree(&(*T)->rchild); /* 销毁右孩子子树 */
		free(*T); /* 释放根结点 */
		*T=NULL; /* 空指针赋0 */
	}
}

void CreateBiTree(BiTree *T)
{ /*按先序次序输入二叉树中结点的值(可为字符型或整型,在主程中 */
	/* 定义),构造二叉链表表示的二叉树T。变量Nil表示空(子)树。有改动 */
	TElemType ch;
	scanf("%d",&ch);
	if(ch==Nil) /* 空 */
		*T=NULL;
	else
	{
		*T=(BiTree)malloc(sizeof(BiTNode));
		if(!*T)
			exit(-1);
		(*T)->data=ch; /* 生成根结点 */
		CreateBiTree(&(*T)->lchild); /* 构造左子树 */
		CreateBiTree(&(*T)->rchild); /* 构造右子树 */
	}
}


void PreOrderTraverse(BiTree T,Status(*Visit)(TElemType))
{ /* 初始条件: 二叉树T存在,Visit是对结点操作的应用函数。算法6.1,有改动 */
	/* 操作结果: 先序递归遍历T,对每个结点调用函数Visit一次且仅一次 */
	if(T) /* T不空 */
	{
		Visit(T->data); /* 先访问根结点 */
		PreOrderTraverse(T->lchild,Visit); /* 再先序遍历左子树 */
		PreOrderTraverse(T->rchild,Visit); /* 最后先序遍历右子树 */
	}
}

void InOrderTraverse(BiTree T,Status(*Visit)(TElemType))
{ /* 初始条件: 二叉树T存在,Visit是对结点操作的应用函数 */
	/* 操作结果: 中序递归遍历T,对每个结点调用函数Visit一次且仅一次 */
	if(T)
	{
		InOrderTraverse(T->lchild,Visit); /* 先中序遍历左子树 */
		Visit(T->data); /* 再访问根结点 */
		InOrderTraverse(T->rchild,Visit); /* 最后中序遍历右子树 */
	}
}


void PostOrderTraverse(BiTree T,Status(*Visit)(TElemType))
{ /* 初始条件: 二叉树T存在,Visit是对结点操作的应用函数 */
	/* 操作结果: 后序递归遍历T,对每个结点调用函数Visit一次且仅一次 */
	if(T) /* T不空 */
	{
		PostOrderTraverse(T->lchild,Visit); /* 先后序遍历左子树 */
		PostOrderTraverse(T->rchild,Visit); /* 再后序遍历右子树 */
		Visit(T->data); /* 最后访问根结点 */
	}
}


Status Visit(TElemType e)//显示
{
	printf("%d ",e);
	return OK;
}


Status InOrderTraverse_use_stack(BiTree T,Status(*Visit)(TElemType))
{ /*非递归算法使用栈 进行前序 中序遍历  后序遍历的思想比较复杂需要使用到二次进栈*/
	
	stack<BiTNode*> S;
	BiTree p=T;
	do
	{
		while(p)
		{ /* 根指针进栈,遍历左子树 */
			Visit(p->data);//先序遍历,先输出节点数据再压入栈
			S.push(p);
			p=p->lchild;
		}
		if(!S.empty())
		{ /* 根指针退栈,访问根结点,遍历右子树 */
			p=S.top();
			//Visit(p->data);//中序遍历,在栈弹出时显示,(需要时将上面的Visit注释掉)
			S.pop();
			p=p->rchild;
		}
	}while(p||!S.empty());
	printf("\n");
	return OK;
}


/*  
后序遍历非递归
后序非递归算法比较复杂,每个结点要到它们左、右子树都遍历完时才得以访问,所以在去遍历它的左、
右子树之前都需要进栈。当它出栈时,需要判断是从左子树回来(即刚遍历完左子树,此时需要去遍历右子树)
,还是从右子树回来(即刚遍历完右子树,此时需要去访问这个结点)。因此,进栈的结点需要伴随着一个标记
tag 
*/
void PostOrderTraverse_use_stack(BiTree T) 
{
	stack<StackNode> S;
	BiTree p; 
	StackNode w;
	p=T;
	do {
		while(p) 
		{
			w.ptr=p;
			w.tag=L;
			S.push(w);
			p=p->lchild;
		}
		int cont_flag=1;
		while( cont_flag&&!S.empty() ) 
		{
			w=S.top();
			S.pop();
			p = w.ptr;
			switch(w.tag) 
			{
			case L :
				w.tag=R;
				S.push(w);
				cont_flag = 0;
				p=p->rchild;
				break;
			case R:
				Visit(p->data);
				break;
			}
		}
	}while(!S.empty() );
}

void LevelOrderTraverse(BiTree T,Status(*Visit)(TElemType))
{ /* 初始条件:二叉树T存在,Visit是对结点操作的应用函数 */
	/* 操作结果:层序递归遍历T(利用队列),对每个结点调用函数Visit一次且仅一次 */
	queue<BiTNode*> qu;
	BiTree p;
	p=T;
	if(T)
	{
		qu.push(p);
		while(!qu.empty())
		{
			p=qu.front();
			qu.pop();
			Visit(p->data);
			if(p->lchild!=NULL)
				qu.push(p->lchild);
			if(p->rchild!=NULL)
				qu.push(p->rchild);
		}
		printf("\n");
	}
}


int main()
{
	//输入: 1 2 3 -1 -1 4 5 -1 7 -1 -1 6 -1 -1 -1
	printf("请输入构造二叉树的值,整数值,空值请输入‘-1’\n");
	BiTree BT;
	InitBiTree(&BT);
	CreateBiTree(&BT);
	printf("\n先序递归遍历递归\n"); 
	PreOrderTraverse(BT,Visit);
	printf("\n中序归遍历递归\n");
	InOrderTraverse(BT,Visit);
	printf("\n后序归遍历递归\n");
	PostOrderTraverse(BT,Visit);
	printf("\n-----------------------\n");
	printf("\n先序递归遍历_非递归\n");
	InOrderTraverse_use_stack(BT,Visit);
	printf("\n后序遍历非递归\n");
	PostOrderTraverse_use_stack(BT);
	printf("\n层次遍历非递归\n");
	LevelOrderTraverse(BT,Visit);
	printf("\n");
	DestroyBiTree(&BT);
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值