树的操作(构造,遍历,求高度,查找)非递归

// BTree1.cpp : 定义控制台应用程序的入口点
//1.使用广义表构造二叉树
//2.程序默认数据为:a(b(c,d),e(,f))
//3.三种遍历使用非递归,求树的高度、查找节点使用递归


#include "stdafx.h"
#include<iostream>
#include<stack>
using namespace std;


#define ElemType char
#define Status int
#define OK 0
#define ERROR 1
#define MAX_LEN 100
typedef struct BTnode
{
	ElemType date;
    BTnode *lchild,*rchild;
}BTnode,*BTree;
typedef enum{L,R} tagtype;
typedef struct 
{
    BTree ptr;
    tagtype tag;
}stacknode;


Status creat(BTree &T,char *str);//根据str创建二叉树T
Status visit(BTree e);//访问节点,打印date
Status preorder(BTree T);//先序遍历,非递归
Status inorder(BTree T);//中序遍历,非递归
Status postorder(BTree T);//后序遍历,非递归
Status getTreeHeight(BTree T,int &H);//求树的高度,递归
Status findNode(BTree T,ElemType e,BTnode &bt);//求树中结点data值为e的节点,并返回此节点的引用


int _tmain(int argc, _TCHAR* argv[])
{
	int i,height,flag;
	BTree T;
	BTnode bt;
	char *buffer,e;
	printf("想输入自己的数据请输入--1or采用默认数据请输入--2:");
	cin>>flag;
	if(flag==1)
	{
		buffer=(char*)malloc(MAX_LEN*sizeof(char));
		scanf("%s",buffer);
	}
	else if(flag==2)
		buffer="a(b(c,d),e(,f))";
	T=NULL;
	creat(T,buffer);//创建树
	//先序遍历
	printf("先序遍历:");
	preorder(T);
	//中序遍历
	printf("\n中序遍历:");
	inorder(T);
	//后序遍历
	printf("\n后序遍历:");
	postorder(T);
	//求树的高度
	height=0;
	getTreeHeight(T,height);
	printf("\n此树的高度为:%d\n",height);
	//查找date值为e的节点并返回节点的引用
	printf("请输入要查找的字符值:");
		cin>>e;
	findNode(T,e,bt);
	if(bt.date==NULL)
		printf("未找到");
	else
		printf("找到他了:%c",bt.date);
	printf("\n");
	system("pause");
	return 0;
}


Status creat(BTree &T,char *str)//初始T=NULL
{
	char *ch;
	int flag=0;
	BTree p;
	stack<BTnode *> Stack; //实例化栈
	p=NULL;
	ch=str;
	while((*ch)!='\0')
	{
		switch(*ch)
		{
		case'(':
			Stack.push(p);
			flag=1;
			break;
		case',':
			flag=2;
			break;
		case')':
			Stack.pop();
			break;
		default://对字符的处理
			p=(BTree)malloc(sizeof(BTnode));
			p->date=*ch;
			p->lchild=p->rchild=NULL;
			if(T==NULL)
				T=p;
			else
			{
				if(flag==1)
					Stack.top()->lchild=p;
				if(flag==2)
					Stack.top()->rchild=p;
			}
		}
		ch++;
	}
	return OK;
}
Status visit(BTree e)
{
	printf("%c",e->date);
	return OK;
}
Status preorder(BTree T)
{
	BTree p;
	stack<BTnode *> Stack; 
	p=T;
	Stack.push(NULL);
	while(p!=NULL)
	{
		visit(p);//访问节点
		if(p->rchild!=NULL)//如果有右孩子,此右孩子节点进栈,
			Stack.push(p->rchild);
		if(p->lchild!=NULL)//向左移动
			p=p->lchild;
		else//左孩子已访问过,p=根—>rchild
		{
			p=Stack.top();
			Stack.pop();
		}
	}
	return OK;
}
Status inorder(BTree T)
{
	BTree p;
	p=NULL;
	stack<BTree> Stack;//实例化栈
	Stack.push(T);//根节点进栈
	while(!Stack.empty())
	{
		while(Stack.top()!=NULL)//一路向左,至最左
			Stack.push(Stack.top()->lchild);
		Stack.pop();//空指针弹出
		if(!Stack.empty())
		{
			p=Stack.top();
			Stack.pop();
			visit(p);
			Stack.push(p->rchild);//向右移动
		}
	}
	return OK;
}
Status postorder(BTree T)
{
	stack<stacknode> Stack;
	stacknode S;
	BTree p;
	p=T;
	do
	{
		while(p!=NULL)//一路向左,进栈,至最左
		{
			S.ptr=p;
			S.tag=L;
			Stack.push(S);
			p=p->lchild;
		}
		while(!Stack.empty()&&Stack.top().tag==R)  
        {
			S=Stack.top();
			Stack.pop();
			p=S.ptr;
            visit(p);   //tag为R,表示右子树访问完毕,故访问根结点       
        }
		if(!Stack.empty())//向右移一个
		{
			Stack.top().tag=R;
			p=Stack.top().ptr->rchild;
		}


	}while(!Stack.empty());
	return OK;
}
Status getTreeHeight(BTree T,int &H)
{
	//递归,分别计算左、右子树的高度,后比较较大者,+1
	int lchildH,rchildH;
	lchildH=rchildH=0;//左右子树高度,初始化
	if(T==NULL)
		H=0;
	else
	{
		getTreeHeight(T->lchild,lchildH);//计算左子树的高度
		getTreeHeight(T->rchild,rchildH);//计算右子树的高度
		if(lchildH>rchildH)
			H=lchildH+1;
		else 
			H=rchildH+1;
	}
	return OK;
}
Status findNode(BTree T,ElemType e,BTnode &bt)
{
	if(T==NULL)//当前BTree为空
	{
		bt.date=NULL;
		return ERROR;
	}
	else if(T->date==e)//找到,当前节点符合
		bt=*T;
	else
	{
		findNode(T->lchild,e,bt);//在左子树中寻找
		if(bt.date==NULL)
			findNode(T->rchild,e,bt);//在右子树中寻找
	}
	return OK;
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值