中序遍历的递归和非递归程序

最近在看树的数据结构,看到树的遍历,于是写了一下树的中序遍历的递归和非递归程序。这里会用到两种数据结构,一种是栈(非递归),一种是二叉树的数据结构。

二叉树的数据结构定义如下:

typedef struct TNode//二叉树结构
{
  char nodeValue;//结点的值
  TNode* left;//左子树
  TNode* right;//右子树
}*BiTree;

栈的数据结构:

typedef struct Sqstack
{
	BiTree *base; //双重指针,base指向一二叉树结点的指针 
	BiTree *top;
	int stacksize;
}Sqstack;

这里栈的空间用于存储结点的指针。stacksize是栈的总空间。

一些涉及栈的元素的操作:

建立空栈:

void  Initstack(Sqstack &S){
	S.base=(BiTree*)malloc(maxstack_size*sizeof(BiTree));
	S.top=S.base;
	S.stacksize=maxstack_size;	
}

判断是否为空栈:

bool stackempt(Sqstack S){
	if(S.base==S.top) return true;
	else return false;
}

元素入栈:

//将一个元素插入栈顶
void push(Sqstack &S,BiTree e){
//如果栈满则重新分配一个increase_size大小的空间给栈 
	if(S.top-S.base>=S.stacksize){
		S.base=(BiTree*)realloc(S.base,(S.stacksize+increase_size)*sizeof(BiTree));
		S.top=S.base+S.stacksize; 
		S.stacksize+=increase_size;
	}
	*S.top=e;
	S.top++;
} 

元素出栈:

//将栈顶元素退出并赋值给e
void pop(Sqstack &S,BiTree &q){
	if(stackempt(S)) return;
	S.top--;
	q=*S.top;

}

接下来就是建立一个二叉树了,先序建立一棵二叉树最简单,程序如下:

void CreateBiTree(BiTree &T)//先序遍历方式创建二叉树 ,输入.代表该结点为空
{
  char nodeValue;
  
  cin>> nodeValue;
  if(nodeValue!='.')//结点非空
  {
    T=new TNode;
    T->nodeValue=nodeValue;
    CreateBiTree(T->left);
    CreateBiTree(T->right);
  }
  else T=NULL;

}

然后是中序遍历的递归程序

//树中根遍历的递归 
void inordervisit(BiTree T){
	 if(T){
	 	inordervisit(T->left);
	 	printf("%c",T->nodeValue);
	 	inordervisit(T->right);
	 }else{
	 //	printf(".");
	 }
}

中序遍历的非递归程序:

//树中根遍历的非递归 
void inorder(BiTree T,Sqstack S){
	if(T){
		BiTree q=T;
		while(q||!stackempt(S)){
			while(q){
				push(S,q);q=q->left;
			}
		//	printf(".");
			pop(S,q);
			printf("%c",q->nodeValue);
			if(q->right){
				q=q->right;
			}else{
		//		printf(".");
				if(!stackempt(S)){
					pop(S,q);
					printf("%c",q->nodeValue);
				} 	//栈若为空则会重复输出最后一个元素值 
				q=q->right;
			}
		}	
	}
}

以下是完整代码段:

#include<stdio.h>
#include<iostream>
#include<malloc.h>
using namespace std;

#define maxstack_size 100
#define increase_size 10

/*树的中根遍历递归和非递归*/
typedef struct TNode//二叉树结构
{
  char nodeValue;//结点的值
  TNode* left;//左子树
  TNode* right;//右子树
}*BiTree;

typedef struct Sqstack
{
	BiTree *base; //双重指针,base指向一二叉树结点的指针 
	BiTree *top;
	int stacksize;
}Sqstack;


void CreateBiTree(BiTree &T)//先序遍历方式创建二叉树 ,输入.代表该结点为空
{
  char nodeValue;
  
  cin>> nodeValue;
  if(nodeValue!='.')//结点非空
  {
    T=new TNode;
    T->nodeValue=nodeValue;
    CreateBiTree(T->left);
    CreateBiTree(T->right);
  }
  else T=NULL;

}

//树中根遍历的递归 
void inordervisit(BiTree T){
	 if(T){
	 	inordervisit(T->left);
	 	printf("%c",T->nodeValue);
	 	inordervisit(T->right);
	 }else{
	 //	printf(".");
	 }
}


//空栈建立 
void  Initstack(Sqstack &S){
	S.base=(BiTree*)malloc(maxstack_size*sizeof(BiTree));
	S.top=S.base;
	S.stacksize=maxstack_size;	
}

//判断一个栈是否为空栈,如果是空栈返回true,否则返回false 
bool stackempt(Sqstack S){
	if(S.base==S.top) return true;
	else return false;
}

//将一个元素插入栈顶
void push(Sqstack &S,BiTree e){
//如果栈满则重新分配一个increase_size大小的空间给栈 
	if(S.top-S.base>=S.stacksize){
		S.base=(BiTree*)realloc(S.base,(S.stacksize+increase_size)*sizeof(BiTree));
		S.top=S.base+S.stacksize; 
		S.stacksize+=increase_size;
	}
	*S.top=e;
	S.top++;
} 

//将栈顶元素退出并赋值给e
void pop(Sqstack &S,BiTree &q){
	if(stackempt(S)) return;
	S.top--;
	q=*S.top;

}

//树中根遍历的非递归 
void inorder(BiTree T,Sqstack S){
	if(T){
		BiTree q=T;
		while(q||!stackempt(S)){
			while(q){
				push(S,q);q=q->left;
			}
		//	printf(".");
			pop(S,q);
			printf("%c",q->nodeValue);
			if(q->right){
				q=q->right;
			}else{
		//		printf(".");
				if(!stackempt(S)){
					pop(S,q);
					printf("%c",q->nodeValue);
				} 	//栈若为空则会重复输出最后一个元素值 
				q=q->right;
			}
		}	
	}
}


int main(){
	BiTree T;
	Sqstack S;
	printf("请按先序序列输入二叉树的结点,“.”代表空结点:\n"); 
	CreateBiTree(T); //建树 
	Initstack(S); //建栈 
	printf("中根遍历的递归输出如下:\n"); 
	inordervisit(T);
	printf("\n中根遍历的非递归输出如下:\n");
	inorder(T,S);
	
	return 0;
} 

内容总结:

在写程序的过程中,应该把被调用程序写在调用程序之前,因为程序是顺序执行。栈空间存储不只是内容,还可以是指针一类的东西。realloc重分配函数的使用

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LXQ.云逸

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值