数据结构实验3---二叉树的遍历(递归、非递归)

#include<iostream>
#include<fstream>
#include<string>
#include<string.h>
#include<stdlib.h>
#define Status int 
#define OK 1 
#define OVERFLOW 0
#define ERROR 0
#define STACK_INIT_SIZE 10
using namespace std;

typedef struct BiTNode{//定义二叉树的结点类型;结构体。
	char data;
	struct BiTNode *lchild, *rchild;
}BiTNode, *BiTree;

typedef struct{//定义线性栈;用于辅助实现二叉树的非递归先序、中序遍历。
	BiTree *base;
	BiTree *top;
	int stacksize;
}SqStack;

typedef struct QNode{//对列的结点类型;结构体。
	BiTree data;
	struct QNode *next;
}QNode, *QueuePtr;

typedef struct{//定义队列类型;链式队列;结构体。
	QueuePtr front;
	QueuePtr rear;
}LinkQueue;


BiTree createBiTree(char * &q){//创建二叉链树函数;先序递归算法。
	//对于递归,数组中的值要依次改变
	//只能是传“指针的引用”,或者是指
	//针的指针,但是也可以用c库函数中的一个用于从文件中逐个的读入的函数fgetc实现
	if(*q == '#')
		return NULL;
	BiTree p = new BiTNode;
	p->data = *q;
	q++;
	p->lchild = createBiTree(q);
	q++;
	p->rchild = createBiTree(q);
	return p;
	return NULL;	
}

void visit(BiTree bt){//访问结点的函数(结点操作函数)。
	if(bt)
		cout<<bt->data<<endl;
}

bool preTraverse(BiTree bt){//二叉树的先序遍历函数;递归算法。
	visit(bt);
	if(bt){
		if(bt->lchild)
			preTraverse(bt->lchild);
		if(bt->rchild)
			preTraverse(bt->rchild);
	}
	return true;
}

bool inTraverse(BiTree bt){//二叉树的中序遍历函数;递归算法。
	if(bt){
		if(bt->lchild)
			inTraverse(bt->lchild);
		visit(bt);
		if(bt->rchild)
			inTraverse(bt->rchild);
	}
	return true;
}
//11-29
bool PostTraverse(BiTree bt){//二叉树的后序遍历函数;递归算法。
	if(bt){
		if(bt->lchild)
			PostTraverse(bt->lchild);
		if(bt->rchild)
			PostTraverse(bt->rchild);
		visit(bt);
	}
	return true;
}

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

Status push(SqStack &s, BiTree &e){//入栈函数。
	if(s.top - s.base >= s.stacksize){
		s.base = (BiTree *)realloc(s.base,
			(s.stacksize + STACK_INIT_SIZE) * sizeof(BiTree));
		if(!s.base)
			exit(OVERFLOW);
		s.top = s.base + s.stacksize;
		s.stacksize += STACK_INIT_SIZE;
	}
	*s.top++ = e;
	return OK;
}

Status pop(SqStack &s, BiTree &e){//出栈函数。
	if(s.top == s.base)
		return ERROR;
	e = * --s.top;
	return OK;
}

Status emptystack(SqStack s){//判定栈空的函数。
	if(s.base == s.top)
		return OK;
	else
		return ERROR;
}

void preordertravese(BiTree bt){//二叉树的先序遍历函数;非递归算法;栈数据结构。
	BiTree p = bt;
	SqStack s;
	InitStack(s);
	while(p||!emptystack(s)){
		if(p){
			visit(p);
			push(s,p);
			p = p->lchild;
		}else{
			pop(s,p);
			p = p->rchild;
		}
	}
}

//-----------------------------
void inordertravese(BiTree bt){//二叉树的中序遍历函数;非递归算法;栈数据结构。
	BiTree p = bt;
	SqStack s;
	InitStack(s);
	while(p||!emptystack(s)){
		if(p){	
			push(s,p);
			p = p->lchild;
		}else{
			pop(s,p);
			visit(p);
			p = p->rchild;
		}
	}
}

//---------------------
Status QueueEmpty(LinkQueue &q){//判定对空函数。
	if(q.front == q.rear)
		return OK;
	else
		return ERROR;
}

Status InitQueue(LinkQueue &q){//队列初始化函数。
	q.front = q.rear = (QueuePtr) malloc (sizeof(QNode));
	if(!q.front)
		exit(OVERFLOW);
	q.front->next = NULL;
	return OK;
}

Status EnQueue(LinkQueue &q, BiTree e){//入队函数。
	QueuePtr p = (QueuePtr) malloc (sizeof(QNode));
	if(!p)
		exit(OVERFLOW);
	p->data = e;
	p->next = NULL;
	q.rear->next = p;
	q.rear = p;
	return OK;
}

Status DeQueue(LinkQueue &q, BiTree &e){//出对函数。
	QueuePtr p;
	if(q.front == q.rear)
		return ERROR;
	p = q.front->next;
	e = p->data;
	q.front->next = p->next;
	if(q.rear == p)
		q.rear = q.front;
	free(p);
	return OK;
}

void LevelOrderTraverse(BiTree T) //二叉树的存续遍历函数;非递归算法;队列数据结构。
{ 
	/* 采用二叉链表存储结构,visit是对数据元素操作的应用函数。*/ 
	/* 层序遍历二叉树T算法(利用队列),对每个数据元素调用函数visit */ 
	LinkQueue q; 
	BiTree p; 
	if(T) 
	{ 
		InitQueue(q); 
		EnQueue(q,T); 
		while(!QueueEmpty(q)) 
		{ 
			DeQueue(q,p); 
			visit(p); 
			if(p->lchild!=NULL) EnQueue(q,p->lchild); 
			if(p->rchild!=NULL) EnQueue(q,p->rchild); 
		} 
	} 
}
//11-29

int main(){//主函数;从文件“xianxu.txt”读取先序字符串序列(以扩展二叉树方式表示)
	//用于创建二叉树,'#'为空结点标记;依次调用各种遍历函数实现二叉树的各种遍历。
	ifstream in("xianxu.txt");
	char a[40];
	string t;
	getline(in, t);
	strcpy_s(a, t.c_str());
	char *p = a;
	BiTree bt = createBiTree(p);
	cout<<"二叉树的先序遍历递归实现:"<<endl;
	preTraverse(bt);
	cout<<endl;
	cout<<"二叉树的中序遍历递归实现:"<<endl;
	inTraverse(bt);
	cout<<endl;
	cout<<"二叉树的后续遍历递归实现:"<<endl;
	PostTraverse(bt);
	cout<<endl;
	cout<<"二叉树的先序遍历非递归实现:"<<endl;
	preordertravese(bt);
	cout<<endl;
	cout<<"二叉树的中序遍历非递归实现:"<<endl;
	inordertravese(bt);
	cout<<endl;
	cout<<"二叉树的层序遍历非递归实现:"<<endl;
	LevelOrderTraverse(bt);
	cout<<endl;
	in.close();
	return 0;
}



3.后序遍历非递归算法
	typedef enum{L,R} tagtype;
typedef struct 
{
	Bitree ptr;
	tagtype tag;
}stacknode;

typedef struct
{
	stacknode Elem[maxsize];
	int top;
}SqStack;

void PostOrderUnrec(Bitree t)
{
	SqStack s;
	stacknode x;
	StackInit(s);
	p=t;

	do 
	{
		while (p!=null)        //遍历左子树
		{
			x.ptr = p; 
			x.tag = L;       //标记为左子树
			push(s,x);
			p=p->lchild;
		}

		while (!StackEmpty(s) && s.Elem[s.top].tag==R)  
		{
			x = pop(s);
			p = x.ptr;
			visit(p->data); //tag为R,表示右子树访问完毕,故访问根结点    
		}

		if (!StackEmpty(s))
		{
			s.Elem[s.top].tag =R;     //遍历右子树
			p=s.Elem[s.top].ptr->rchild;       
		} 
	}while (!StackEmpty(s));
}//PostOrderUnrec 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值