非递归算法实现树的先序遍历,中序遍历,后序遍历;也有树的层次遍历。

#include <stdio.h>
#include <stdlib.h>
#define N 30

typedef struct TNode *BiT;
typedef struct SNode *Stack;

struct SNode{
	int top;
	BiT data[N];
};

struct TNode{
	int data;
	BiT lchild, rchild;
};


void CreateStack(Stack *s) {
	(*s) = (Stack) malloc (sizeof(struct SNode));
	(*s)->top = -1;
} 

void push(Stack *s, BiT e) {
	if((*s)->top == N - 1)
	{
		printf("栈满");
		return; 
	}
	(*s)->data[++(*s)->top] = e; 
}

BiT pop(Stack *s) {
	if((*s)->top == -1)
	{
		printf("栈为空");
		return 0; 
	}
	return (*s)->data[(*s)->top--];
}

int Isempty(Stack s) {
	if(s->top == -1)
		return 1;
	else
		return 0; 
}

BiT getTop(Stack s) {
	return s->data[s->top];
}

void CreateBiT(BiT *T) {
	int n;
	scanf("%d",&n); 
	if(n == 0)
		(*T) = 0;
	else
	{
		(*T) = (BiT)malloc(sizeof(struct TNode)); 
		(*T)->data = n;
		CreateBiT(&(*T)->lchild);
		CreateBiT(&(*T)->rchild); 
	}
}

void preTraverse(BiT T) {
	Stack s;
	CreateStack(&s);
	BiT pCur = T;		//指向当前访问节点 
	while(pCur || !Isempty(s)) {	//当前节点和栈为空时,循环结束 
		//从根节点开始,输出根节点,并将其入栈,把左孩子置为当前节点,直至没有左孩子,当前节点为空。
		printf("%d ",pCur->data);
		push(&s,pCur);
		pCur = pCur->lchild;
		//如果当前节点pCur为0且栈不空,则将栈顶节点出栈,  
		//同时置其右孩子为当前节点,循环判断,直至pCur不为空   
		while(!pCur && !Isempty(s))
		{
			pCur = pop(&s);
			pCur = pCur->rchild;
		}	 
		
	}
	
}

void inTraverse(BiT T) {
	Stack s;
	CreateStack(&s);
	BiT pCur = T;
	//直到当前节点为空且栈空时,循环结束 
	while(pCur || !Isempty(s)) {
		if(pCur->lchild)
		{
			//左孩子不为空,则入栈,将左孩子置为当前节点
			push(&s, pCur);
			pCur = pCur->lchild; 
		}
		else
		{
			//如果左孩子为空,则输出当前节点,将右孩子设为当前节点,判断是否为空
			printf("%d ", pCur->data);
			pCur = pCur->rchild;
			//如果为空,且栈不为空,栈顶节点,出栈输出栈顶元素,
			//同时将右孩子设为当前节点,继续判断 ,直到当前节点不为空
			while(!pCur && !Isempty(s))
			{
				pCur = pop(&s);
				printf("%d ", pCur->data);
				pCur = pCur->rchild;
			}
		}
		 
	} 
}

void behTraverse(BiT T) {
	Stack s;
	CreateStack(&s);
	BiT pCur = T;
	BiT pPre = 0;
	push(&s, T);
	while(!Isempty(s))
	{
		pCur = getTop(s);	//当前节点置为栈顶节点
		if((pCur->lchild == 0 && pCur->rchild == 0) || (pPre != 0 && (pCur->lchild == pPre) || pCur->rchild == pPre))
		{
			//如果当前节点没有左右孩子,或者有左孩子或有孩子,但已经被访问输出,
			//则直接输出该节点,将出栈,将其设为上一个访问的节点
			printf("%d ",pCur->data);
			pPre = pop(&s); 
		}
		else
		{
			//如果不满足上面两种情况,则将其左右孩子依次入栈
			if(pCur->rchild != 0)
			push(&s, pCur->rchild);
			if(pCur->lchild != 0)
			 push(&s, pCur->lchild);
		} 
		
	} 
}

void levelTraverse(BiT T) {
	int front = 0;
	int rear = 0;
	BiT BiTQue[N];
	BiT tempBNode;
	if(T) {
		BiTQue[rear++] = T;
	}
	while(front != rear) {
		tempBNode = BiTQue[front++];
		printf("%d ", tempBNode->data);
		if(tempBNode->lchild)
		BiTQue[rear++] = tempBNode->lchild;
		if(tempBNode->rchild)
		BiTQue[rear++] = tempBNode->rchild;
	}
} 

int main()
{
	BiT T;
	CreateBiT(&T);
	printf("非递归的前序遍历:");
	preTraverse(T); 
	printf("\n");
	printf("非递归的中序遍历:");
	inTraverse(T);
	printf("\n");
	printf("非递归的后序遍历:");
	behTraverse(T);
	printf("\n");
	printf("树的层次遍历:");
	levelTraverse(T); 
	return 0;
} 


  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1.先序遍历非递归算法#define maxsize 100typedef struct{ Bitree Elem[maxsize]; int top;}SqStack;void PreOrderUnrec(Bitree t){ SqStack s; StackInit(s); p=t; while (p!=null || !StackEmpty(s)) { while (p!=null) //遍历左子 { visite(p->data); push(s,p); p=p->lchild; }//endwhile if (!StackEmpty(s)) //通过下一次循环中的内嵌while实现右子遍历 { p=pop(s); p=p->rchild; }//endif }//endwhile }//PreOrderUnrec2.中序遍历非递归算法#define maxsize 100typedef struct{ Bitree Elem[maxsize]; int top;}SqStack;void InOrderUnrec(Bitree t){ SqStack s; StackInit(s); p=t; while (p!=null || !StackEmpty(s)) { while (p!=null) //遍历左子 { push(s,p); p=p->lchild; }//endwhile if (!StackEmpty(s)) { p=pop(s); visite(p->data); //访问根结点 p=p->rchild; //通过下一次循环实现右子遍历 }//endif }//endwhile}//InOrderUnrec3.后序遍历非递归算法#define maxsize 100typedef 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; visite(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、付费专栏及课程。

余额充值