个人笔记--二叉树的链式存储与前、中、后、层序遍历

二叉树

创建树:

ABC$$DE$G$$F$$$

在这里插入图片描述

最主要的,结构体的构建

#define OK 1
#define ERROR 0
#define MAX_TREE_SIZE 100//树的初始空间大小
#define STACK_INIT_SIZE 100//栈的初始空间大小
#define STACKINCREMENT 10//增栈
typedef char TElemType;//树中存储的是字符
typedef bool Status;

typedef struct BiTNode{
	TElemType data;//数据域
	struct BiTNode *lchild ,*rchild;//指针域
}BiTNode,*BiTree;
BiTree T;

typedef BiTree SElemType;//栈里存的是指针
typedef struct{
	SElemType *base;
	SElemType *top;
	int stacksize;
}SqStack;

用到的栈子函数(详细了解栈点击传送

Status InitStack(SqStack &S)//初始化栈
{
	S.base=(SElemType *)malloc(STACK_INIT_SIZE * sizeof(SElemType));
	if(!S.base) exit(OVERFLOW);
	S.top=S.base;
	S.stacksize=STACK_INIT_SIZE;
	return OK;
}

Status PushStack(SqStack &S,SElemType p)//入栈
{
	if(S.top-S.base>=S.stacksize)
	{
		S.base=(SElemType *)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(SElemType));
		if(!S.base)	exit(OVERFLOW);
		S.top=S.base+S.stacksize;
		S.stacksize+=STACKINCREMENT;
	}
	*S.top++ = p;
	return OK;
}

Status PopStack(SqStack &S,SElemType &p)//出栈
{
	if(S.top == S.base)	return ERROR;
	p=*--S.top;
	return OK;
}

Status TopStack(SqStack &S,SElemType &p)//取栈顶元素
{
	if(S.top==S.base)
		return ERROR;
	p=*(S.top-1);
	return OK;
}

步入正题

1.创建树

Status createBiTree(BiTree &T)
{
	char ch;
	cin>>ch;//字符型数据
	if(ch=='$')
		T=NULL;//如果输入为'$',说明该结点为空
	else
	{
		if(!(T=(BiTNode *)malloc(sizeof(BiTNode)))) exit(OVERFLOW);
		T->data=ch;//存储
		createBiTree(T->lchild);//访问该结点的左结点
		createBiTree(T->rchild);//访问该结点的右结点
	}
	return OK;
}

(输出结点的数据)//这个子函数不是写在其他函数内的,是供其他函数反复调用的 啊啊啊卡了好久

Status Print(TElemType e)
{
	printf("%c ",e);//just输出字符型变量e
	return OK;
}

2.先序遍历//递归方法

Status preTree(BiTree &T,Status(* visit)(TElemType e))
//第二个参数就是用来调用Print函数的
{
	if(T)
	{
		if(visit(T->data))//输出写在最前面,就是先序遍历
			if(preTree(T->lchild,Print))//接着访问左子树(递归)
				if(preTree(T->rchild,Print))//最后访问右子树
					return OK;
		return ERROR;
	}
	return OK;
}

3.后序遍历//递归方法

Status postTree(BiTree &T,Status(* visit)(TElemType e))
{
	if(T)
	{
		if(postTree(T->lchild,Print))
			if(postTree(T->rchild,Print))
				if(visit(T->data))//同理,输出放在最后面就是后序遍历
					return OK;
		return ERROR;
	}
	return OK;
}

4.中序遍历的递归方法就不写了,就是把输出函数放在两个递归子树中间即可。
这里说一下中序遍历的两种非递归(用栈模拟)算法:
(一)通过不断地取栈顶元素

Status inTree1(BiTree T,Status(* visit)(TElemType e))
{
	SqStack S;
	InitStack(S);//初始化一个栈S
	SElemType p;
	PushStack(S,T);//根指针入栈 
	while(S.top!=S.base)
	{
		while(TopStack(S,p) &&  p)
			PushStack(S,p->lchild);//向左走到尽头,取最后一个结点的左子树(我们知道是空的,所以下一步出栈)
		PopStack(S,p);//空指针出栈
		if(S.top!=S.base)//访问结点
		{
			PopStack(S,p);//出栈
			if(!visit(p->data))//输出该结点的数据域(此时该结点已出栈)
				return ERROR;
			PushStack(S,p->rchild);//访问该结点的右子树(若为空,则进行下一次循环时首先会出栈)
		}
	}
}//手动模拟一下就懂了

(二)通过不断地入栈出栈

Status inTree2(BiTree T,Status(* visit)(TElemType e))
{
	SqStack S;
	InitStack(S);
	SElemType p;
	p=T;
	while(p || S.top!=S.base)
	{
		if(p)
		{
			PushStack(S,p);//根指针入栈
			p=p->lchild;//遍历左子树
		}
		else
		{
			PopStack(S,p);//根指针出栈
			if(!visit(p->data))//输出根结点
				return ERROR;
			p=p->rchild;//遍历右子树
		}
	}
	return OK;
}

5.层序遍历

Status cengTree(BiTree &T,Status(* visit)(TElemType e))
{
	int i=0,j=0;//i用来访问,j用来存
	BiTree p[100];//数指针数组
	if(T)
		p[j++]=T;
	while(i<j)
	{
		visit(p[i]->data);//每访问一个结点,就把它的左右子树存进数组里
		if(p[i]->lchild)
			p[j++]=p[i]->lchild;
		if(p[i]->rchild)
			p[j++]=p[i]->rchild;
		i++;
	}
}

6.求树的深度

int DeepTree(BiTree T)
{
	int LD,RD;//LD指最远左子树深度,RD指最远右子树深度
	if(T==NULL)
		return 0;
	else
	{
		LD=DeepTree(T->lchild);//递归
		RD=DeepTree(T->rchild);
		return (LD>=RD?LD:RD)+1;//最后加上根节点那一层
	}
}

完整代码如下:

#include<bits/stdc++.h>
#include<cstdio>
using namespace std;
#define OK 1
#define ERROR 0
#define MAX_TREE_SIZE 100
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
typedef char TElemType;
typedef bool Status;
typedef struct BiTNode{
	TElemType data;
	struct BiTNode *lchild ,*rchild;
}BiTNode,*BiTree;
BiTree T;

typedef BiTree SElemType;
typedef struct{
	SElemType *base;
	SElemType *top;
	int stacksize;
}SqStack;
Status InitStack(SqStack &S)
{
	S.base=(SElemType *)malloc(STACK_INIT_SIZE * sizeof(SElemType));
	if(!S.base) exit(OVERFLOW);
	S.top=S.base;
	S.stacksize=STACK_INIT_SIZE;
	return OK;
}

Status PushStack(SqStack &S,SElemType p)
{
	if(S.top-S.base>=S.stacksize)
	{
		S.base=(SElemType *)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(SElemType));
		if(!S.base)	exit(OVERFLOW);
		S.top=S.base+S.stacksize;
		S.stacksize+=STACKINCREMENT;
	}
	*S.top++ = p;
	return OK;
}

Status PopStack(SqStack &S,SElemType &p)
{
	if(S.top == S.base)	return ERROR;
	p=*--S.top;
	return OK;
}

Status TopStack(SqStack &S,SElemType &p)
{
	if(S.top==S.base)
		return ERROR;
	p=*(S.top-1);
	return OK;
}


Status createBiTree(BiTree &T)
{
	char ch;
	cin>>ch;
	if(ch=='$')
		T=NULL;
	else
	{
		if(!(T=(BiTNode *)malloc(sizeof(BiTNode)))) exit(OVERFLOW);
		T->data=ch;
		createBiTree(T->lchild);
		createBiTree(T->rchild);
	}
	return OK;
}

Status Print(TElemType e)
{
	printf("%c ",e);
	return OK;
}
	
Status preTree(BiTree &T,Status(* visit)(TElemType e))
{
	if(T)
	{
		if(visit(T->data))
			if(preTree(T->lchild,Print))
				if(preTree(T->rchild,Print))
					return OK;
		return ERROR;
	}
	return OK;
}

Status inTree1(BiTree &T,Status(* visit)(TElemType e))
{
	SqStack S;
	InitStack(S);
	SElemType p;
	PushStack(S,T);
	while(S.top!=S.base)
	{
		while(TopStack(S,p) &&  p)
			PushStack(S,p->lchild);
		PopStack(S,p);
		if(S.top!=S.base)
		{
			PopStack(S,p);
			if(!visit(p->data))
				return ERROR;
			PushStack(S,p->rchild);
		}
	}
}

Status inTree2(BiTree T,Status(* visit)(TElemType e))
{
	SqStack S;
	InitStack(S);
	SElemType p;
	p=T;
	while(p || S.top!=S.base)
	{
		if(p)
		{
			PushStack(S,p);
			p=p->lchild;
		}
		else
		{
			PopStack(S,p);
			if(!visit(p->data))
				return ERROR;
			p=p->rchild;
		}
	}
	return OK;
}

Status postTree(BiTree &T,Status(* visit)(TElemType e))
{
	if(T)
	{
		if(postTree(T->lchild,Print))
			if(postTree(T->rchild,Print))
				if(visit(T->data))
					return OK;
		return ERROR;
	}
	return OK;
}

Status cengTree(BiTree &T,Status(* visit)(TElemType e))
{
	int i=0,j=0;
	BiTree p[100];
	if(T)
		p[j++]=T;
	while(i<j)
	{
		visit(p[i]->data);
		if(p[i]->lchild)
			p[j++]=p[i]->lchild;
		if(p[i]->rchild)
			p[j++]=p[i]->rchild;
		i++;
	}
}

int DeepTree(BiTree T)
{
	int LD,RD;
	if(T==NULL)
		return 0;
	else
	{
		LD=DeepTree(T->lchild);
		RD=DeepTree(T->rchild);
		return (LD>=RD?LD:RD)+1;
	}
}

int main()
{
	cout<<"***********************************************"<<endl;
	cout<<"************ 1.创建二叉树      *****************"<<endl;
	cout<<"************ 2.先序遍历二叉树  *****************"<<endl;
	cout<<"************ 3.中序遍历二叉树1 *****************"<<endl;
	cout<<"************ 4.中序遍历二叉树2 *****************"<<endl;
	cout<<"************ 5.后序遍历二叉树  *****************"<<endl;
	cout<<"************ 6.层序遍历二叉树  *****************"<<endl;
	cout<<"************ 7.求二叉树的深度  *****************"<<endl;
	cout<<"************ 8.退出            ****************"<<endl;
	cout<<"***********************************************"<<endl;
	
	int n;
	do
	{
		cout<<"请输入选择:" ;
		cin>>n;
		switch(n)
		{
			case 1:
				cout<<"输入:"; 
				createBiTree(T);
				cout<<"创建成功"<<endl;
				break;
			case 2:
				cout<<"前序遍历:"; 
				preTree(T,Print);
				cout<<endl;
				break;
			case 3:
				cout<<"中序遍历1:"; 
				inTree1(T,Print);
				cout<<endl;
				break;
			case 4:
				cout<<"中序遍历2:"; 
				inTree2(T,Print);
				cout<<endl; 
				break;
			case 5:
				cout<<"后序遍历:"; 
				postTree(T,Print);
				cout<<endl;
				break;
			case 6:
				cout<<"层序遍历:"; 
				cengTree(T,Print);
				cout<<endl; 
				break;
			case 7:
				cout<<"该二叉树的深度是:";
				cout<<DeepTree(T)<<endl;
				break;
			default :
				cout<<"输入指令不存在"<<endl; 
				break;
		}
	}while(n!=8);
	cout<<"程序已退出,欢迎下次使用"<<endl;
	return 0;
}

I can do it.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值