二叉树的遍历算法递归与非递归实现

文章目录

      • 递归实现
        • 核心部分
        • 完整代码
        • 运行结果
      • 非递归实现
        • 核心部分
        • 完整代码
        • 运行结果

递归实现

二叉树图
二叉树的遍历算法递归与非递归实现_第1张图片

核心部分


//前序遍历 根左右 
void preOrder(BTreeNode *btNode){
	if(btNode==NULL){
		return;
	}
	visit(btNode);
	preOrder(btNode->left);
	preOrder(btNode->right);
}

//中序遍历  左根右
void midOrder(BTreeNode *btNode){
	if(btNode==NULL){
		return;
	}
	midOrder(btNode->left);
	visit(btNode);
	midOrder(btNode->right);
}

//后序遍历  左右根
void afterOrder(BTreeNode *btNode){
	if(btNode==NULL){
		return;
	}
	afterOrder(btNode->left);
	afterOrder(btNode->right);
	visit(btNode);
}
//二叉树的层次遍历 
void LevelOrder(LQueue *Q,BTreeNode *btNode){
	BTreeNode *p;
	EnQueue(Q,btNode);
	//out<<"2"<
	//cout<front->data->data<<" ";
	while(!isEmpty(*Q)){
		//cout<<"1"<
		OutQueue(Q,p);
		//cout<data<<" ";
		visit(p);
		//cout<left->data<<" "		;
		if(p->left!=NULL)
		{
			EnQueue(Q,p->left);
			//EnQueue(Q,p->right);
		}			
		if(p->right!=NULL){
			//EnQueue(Q,p->left);
			EnQueue(Q,p->right);
		}	
	}
}

完整代码

#include
using namespace std;

typedef char ElemType;
//二叉树的定义 
typedef struct BTreeNode{
	ElemType data;
	struct	BTreeNode *left;//左孩子
	struct	BTreeNode *right;//右孩子
}BTreeNode;

//队列中结点的定义 
typedef struct qnode {
	BTreeNode *data;
	struct qnode *next;
}LQNode;
//队列的定义 
typedef struct {
	LQNode *front;//队头指针
	LQNode *rear;//队尾指针
}LQueue;

//二叉树初始化
void BTreeInit(BTreeNode *root){
	root=(BTreeNode *)malloc(sizeof(BTreeNode));
	root->left=NULL;
	root->right=NULL;
}
 
//添加左孩子 
int addLeftKid(BTreeNode *btNode,ElemType ldata) {
	//分配新结点
	BTreeNode * lNode=(BTreeNode *)malloc(sizeof(BTreeNode));
	//初始化结点数据
	lNode->data=ldata;
	//cout<data<<" ";
	lNode->left=NULL;
	lNode->right=NULL;
	//将当前初始化的结点添加到父节点之下
	btNode->left=lNode;
	return 1;	
}	

//添加右孩子 
int addRightKid(BTreeNode *btNode,ElemType rdata) {
	//分配新结点
	BTreeNode * rNode=(BTreeNode *)malloc(sizeof(BTreeNode));
	//初始化结点数据
	rNode->data=rdata;
	//cout<data<<" ";
	rNode->left=NULL;
	rNode->right=NULL;
	//将当前初始化的结点添加到父节点之下
	btNode->right=rNode;
	return 1;	
}

//访问结点数据 
void visit(BTreeNode *btNode){
	cout<<btNode->data<<" ";
}

//前序遍历 根左右 
void preOrder(BTreeNode *btNode){
	if(btNode==NULL){
		return;
	}
	visit(btNode);
	preOrder(btNode->left);
	preOrder(btNode->right);
}

//中序遍历  左根右
void midOrder(BTreeNode *btNode){
	if(btNode==NULL){
		return;
	}
	midOrder(btNode->left);
	visit(btNode);
	midOrder(btNode->right);
}

//后序遍历  左右根
void afterOrder(BTreeNode *btNode){
	if(btNode==NULL){
		return;
	}
	afterOrder(btNode->left);
	afterOrder(btNode->right);
	visit(btNode);
}

//队列初始化
void QueueInit(LQueue *Q) {
	Q->front=NULL;
	Q->rear=NULL;	
}

//入队
void EnQueue(LQueue *Q,BTreeNode *btNode) {
	//cout<data<<" ";
	//申请一个新的队列结点 
	LQNode* p=(LQNode *)malloc(sizeof(LQNode));
	//将当前的二叉树结点入队
	p->data= btNode;
	//cout<data->data<<" ";
	p->next=NULL;
	if(Q->rear!=NULL)//队尾不空,也就是当前队列不为空
		Q->rear->next=p;//将当前新申请的结点入队
	Q->rear=p;//将p更改为队尾指针	
	if(Q->front==NULL)//如果队列为空,将p修改为队头指针 脑子一热在if里面少写了个等号,改bug改了一下午,艹 
		Q->front=p; 
	//cout<rear->data->data<<" ";
}

//出队
int  OutQueue(LQueue *Q,BTreeNode * &btNode) {
	LQNode *p;
	if(Q->front==NULL){
		cout<<"当前队头为空,队列已无数据!"<<endl;
		return 0;
	}
	btNode=Q->front->data;
	//cout<<*(btNode->data)<<" ";

	p=Q->front;
	//当前队头为队头下一个元素,将当前队头出队 
	Q->front=Q->front->next;
	/*如果当前队头为空,也就是
	说队头之后下一个元素为空,
	删除最后一个结点,将尾指针置空。 
	*/ 
	if(Q->front==NULL){
		//cout<<"当前队头为空!";
		Q->rear=NULL;
	}
		
	//free(p);
	return 1;
}

//判断队列是否为空
int isEmpty(LQueue Q) {
	return (Q.front==NULL)?1:0;
}

//二叉树的层次遍历 
void LevelOrder(LQueue *Q,BTreeNode *btNode){
	BTreeNode *p;
	EnQueue(Q,btNode);
	//out<<"2"<
	//cout<front->data->data<<" ";
	while(!isEmpty(*Q)){
		//cout<<"1"<
		OutQueue(Q,p);
		//cout<data<<" ";
		visit(p);
		//cout<left->data<<" "		;
		if(p->left!=NULL)
		{
			EnQueue(Q,p->left);
			//EnQueue(Q,p->right);
		}			
		if(p->right!=NULL){
			//EnQueue(Q,p->left);
			EnQueue(Q,p->right);
		}	
	}
}

int main() {
	char a[]={'A','B','C','D','E','F','G'};
	BTreeNode root;//根节点
	BTreeInit(&root);
	root.data='A' ;
	addLeftKid(&root,'B');
	addRightKid(&root,'C');
	//给'B'添加左右孩子 
	addLeftKid(root.left,'D');
	addRightKid(root.left,'E');
	//给'C'添加左右孩子 
	addLeftKid(root.right,'F');
	addRightKid(root.right,'G');

	cout<<"前序遍历结果为:";
	preOrder(&root);
	cout<<"\n中序遍历结果为:";
	midOrder(&root);
	cout<<"\n后序遍历结果为:";
	afterOrder(&root);
	cout<<endl;
	cout<<"层序遍历结果为:";
	
	LQueue Q;
	QueueInit(&Q);
	LevelOrder(&Q,&root);
	//cout<left->data;
	return 0;
}

运行结果

二叉树的遍历算法递归与非递归实现_第2张图片

非递归实现

核心部分


//先序遍历(非递归) 
void  PreOrder(BitTree T) {
	LinkStack S;
	StakInit(S);
	BitTree p =T;
	while(p||!IsEmpty(S)){
		if(p){
			visit(p);
			Push(S,p);
			p=p->lc;
		}else{
			Pop(S,p);
			p=p->rc;
		}
	}
}

//中序遍历(非递归) 
void  InOrder(BitTree T) {
	LinkStack S;
	StakInit(S);
	BitTree p =T;
	while(p||!IsEmpty(S)){
		//p不为空,栈不空 
		if(p){
			Push(S,p);
			p=p->lc;
		}else{
			Pop(S,p);
			visit(p);
			p=p->rc;
		}
	}
}

//后序遍历(非递归) 
void  PostOrder(BitTree T) {
	LinkStack S;
	StakInit(S);
	BitTree  r,p=T;
	r=NULL;
	while(p||!IsEmpty(S)){
		if(p){
			Push(S,p);
			p=p->lc;
		}else{
			GetTop(S,p);//读栈顶,非出栈 
			if(p->rc&&p->rc!=r){//若右子树存在,且未被访问过 
				p=p->rc;
			}else{
				Pop(S,p);//将结点弹出 
				visit(p);//访问该节点 
				r=p;//记录最近访问过的结点 
				p=NULL;
			}
		}
	}
}

完整代码

#include
using namespace std;
typedef char ElemType;

//树 
typedef struct btree{
	ElemType data;
	struct btree *lc,*rc;
}BitNode,*BitTree;


// 链栈 
typedef struct Lnode{
	BitNode* data ;
	struct Lnode *next;
}Lnode,*LinkStack;


//二叉树初始化
void BitTreeInit(BitTree &T){
	T=(BitTree )malloc(sizeof(BitTree));
	T->lc=NULL;
	T->rc=NULL;
}

//插入左孩子
bool addLeftchild(BitTree &T,ElemType x) {
	BitNode *p=(BitNode *)malloc(sizeof(BitNode));
	if(p==NULL){
		//分配空间失败 
		return false;
	}
	p->data=x;
	p->lc=NULL;
	p->rc=NULL;
	T->lc=p;
	return true; 
}
 
//插入右孩子
bool addRightchild(BitTree &T,ElemType x) {
	BitNode *p=(BitNode *)malloc(sizeof(BitNode));
	if(p==NULL){
		//分配空间失败 
		return false;
	}
	p->data=x;
	p->lc=NULL;
	p->rc=NULL;
	T->rc=p;
	return true; 
} 

//访问结点
void visit(BitTree &T) {
	cout<<T->data<<" ";
}
 
//递归遍历树,求树的深度 
int treeDeep(BitTree &T) {
	if(T==NULL){
		return 0;
	}else{
		int l=treeDeep(T->lc);
		int r=treeDeep(T->rc);
		return r>l?r+1:l+1;
	}
}

//初始化
void  StakInit(LinkStack &S){
	S=NULL;
}

//判空
bool IsEmpty(LinkStack S) {
	return S==NULL;
}


//入栈
bool Push(LinkStack &S, BitNode * e ) {
	Lnode  *p=(Lnode *)malloc(sizeof(Lnode));
	if(p==NULL){
		//分配空间失败
		return false; 
	}
	
	p->data=e;
	p->next=S;
	S=p;
	return true;
}

//出栈 
bool Pop(LinkStack &S,BitNode * &e){

	if(S==NULL){
		//如果栈空 
		return false;
	}
	e=S->data; 
	Lnode *p=S;// 
	S=S->next;

	free(p);
	return true;	 
}

//获取栈顶元素
bool GetTop(LinkStack &S,BitNode * &e){
	if(S==NULL){
		return false; 
	}
	e=S->data;
	return true;
} 



//先序遍历(非递归) 
void  PreOrder(BitTree T) {
	LinkStack S;
	StakInit(S);
	BitTree p =T;
	while(p||!IsEmpty(S)){
		if(p){
			visit(p);
			Push(S,p);
			p=p->lc;
		}else{
			Pop(S,p);
			p=p->rc;
		}
	}
}

//中序遍历(非递归) 
void  InOrder(BitTree T) {
	LinkStack S;
	StakInit(S);
	BitTree p =T;
	while(p||!IsEmpty(S)){
		//p不为空,栈不空 
		if(p){
			Push(S,p);
			p=p->lc;
		}else{
			Pop(S,p);
			visit(p);
			p=p->rc;
		}
	}
}

//后序遍历(非递归) 
void  PostOrder(BitTree T) {
	LinkStack S;
	StakInit(S);
	BitTree  r,p=T;
	r=NULL;
	while(p||!IsEmpty(S)){
		if(p){
			Push(S,p);
			p=p->lc;
		}else{
			GetTop(S,p);//读栈顶,非出栈 
			if(p->rc&&p->rc!=r){//若右子树存在,且未被访问过 
				p=p->rc;
			}else{
				Pop(S,p);//将结点弹出 
				visit(p);//访问该节点 
				r=p;//记录最近访问过的结点 
				p=NULL;
			}
		}
	}
}

int main(){
	BitTree T;
	BitTreeInit(T) ;
	T->data='A';
	addLeftchild(T,'B');
	addRightchild(T,'C');
	
	//给'B'添加左右孩子
	addLeftchild(T->lc,'D');
	addRightchild(T->lc,'E');
	/*
	addLeftchild(T->rc,'F');
	addRightchild(T->rc,'G');*/
	
	//先序 
	PreOrder(T);
	cout<<endl;
	//中序 
	InOrder(T);
	cout<<endl;
	//后序 
	PostOrder(T); 
	return 0;
}

运行结果

二叉树的遍历算法递归与非递归实现_第3张图片

你可能感兴趣的:(C++,数据结构,算法,c++,数据结构)