C语言实现二叉树的各种递归非递归遍历(前序、后序、中序、层级遍历)

二叉树遍历
#include <stdio.h>
#include <stdlib.h>
#define NULL 0
#define M 100
//定义结构体 
// 定义一个用于存储节点的二叉树,用于数据的存储,和后面遍历取值 
typedef struct node  
{  
    int data;
	int count;//count是为了计数用。在后序遍历中,子树的根节点在第一次遍历的时候不会输出,只有在第二次遍历的时候才输出。
    struct node *lchild;  
    struct node *rchild;  
}binaryTree;
 
// 定义一个储存树节点的栈,方便遍历的时候追踪到树的地址。
typedef struct stack 
{
	binaryTree *elements[M];
	int top;
}sequenceStack;
// 定义一个存储树节点的队列
typedef struct queue {
	binaryTree *queueNum[M];
	int front;
	int rear;
}sequenceQueue; 

// 定义操作变量 
binaryTree *root;//定义一个树根
sequenceStack s;//定义栈
sequenceQueue q;//定义队列 

//操作栈的一些方法 
//初始化栈
void setNull()
{
	s.top =0;
}
 
//入栈操作,就是将元素加入定义好的栈中 
void push(binaryTree *temp)
{
	s.elements[s.top++] = temp;
}
 
binaryTree *pop()//取栈顶并出栈顶
{
	return s.elements[--s.top];//先计算,再取值 
}
 
int empty()//判断空栈
{
	return s.top == 0;
}
//操作队列的一些方法
//初始化队列 
void initialQueue() {
	q.front = 0;
	q.rear = 0;
} 
//入队列
void pushElement(binaryTree * temp) {
	q.queueNum[q.rear++] = temp;
} 
//出队列
binaryTree *popElement() {
	return q.queueNum[q.front++];
} 

int emptyQueue() {
	return q.front == q.rear;
}
 
 // 构建二叉树 
binaryTree *creatBinaryTree(){
	binaryTree *t;
  	int x;
 	 scanf("%d",&x);
  	// 当我们输入的数字为 0 时,就将其对应的节点置空,放到了二叉树的最后 
  	if(x==0){
	   t=NULL; /*以x=0表示输入结束*/
	} else {
		//动态生成结点t,分别给结点t的数据域、左右孩子域
  		t=(binaryTree*)malloc(sizeof(binaryTree));  
 	 	t->data=x;
		//赋值,给左右孩子域赋值时用到了递归的思想。                 
  		t->lchild=creatBinaryTree();
  		t->rchild=creatBinaryTree();
  	}
  return t;
}

//前序遍历的非递归算法
void preOrderWithoutRecursion(binaryTree *t)
{
	binaryTree *temp = t;//定义一个树节点,用它来遍历
	while(temp != NULL || s.top != 0)
	{
		while(temp != NULL)//先遍历左孩子,并输出。
		{
			printf("%5d",temp->data);
			//这里将不停的入栈,是为了在遍历完左子树,之后遍历右子树时,进行根节点的查找 
			push(temp);
			temp = temp->lchild;
		}
		//当左孩子遍历完后,取栈顶,找右孩子。此时循环还没有结束,再遍历它的左孩子,直至孩子全部遍历结束。
		// 这里判断栈中是否还有元素,如果有的话,说明,右子树不为空,继续进行非递归前序遍历 
		if(s.top != 0)
		{
			//这里的弹栈和上面的入栈操作是一一对应的, 
			temp = pop();
			temp = temp->rchild;
		}
	}
	printf("\n");
}
 
//中序遍历的非递归算法
void inOrderWithoutRecursion(binaryTree *t)
{
	binaryTree *temp = t;
	while(temp != NULL||s.top != 0)
	{
		while(temp != NULL)//先把左孩子入栈,所有左孩子入栈结束
		{ 
			push(temp);
			temp = temp->lchild;
		}
		if(s.top != 0)//左孩子入栈结束,取栈顶,输出栈顶元素,遍历右孩子
		{
			temp = pop();
			printf("%5d",temp->data);
			temp = temp->rchild;
		}
	}
	printf("\n");
}
 
 
 //后序遍历的非递归算法
void postOrderWithoutRecursion(binaryTree *root)
{
    binaryTree *temp = root;
	while(temp!=NULL||s.top!=0) {
        while(temp!= NULL) {
        	//当元素首次被访问时,我们将该元素进行标记,说明它是首次访问 
            temp->count=1;       
            push(temp);
            temp=temp->lchild;
        }
        if(s.top!=0) {
        	//弹栈 
            temp=pop(); 
            //说明该元素是第一次出现在栈中 
            if(temp->count == 1) {
                temp->count++;
                //再次入栈,并将标志位加一 
                push(temp);
                temp=temp->rchild;
            }
            else {
            	//进行判读当前节点的访问状态,
				//如果是 2,就说明已经遍历了该结点的左子树,也就是能够进行后序遍历输出的操作
				if(temp->count==2) {
                printf("%5d",temp->data);
                temp=NULL;
				}	
			}
            
        }
    }
	printf("\n");
}

//前序遍历的递归算法
void preOrderWithRecursion(binaryTree *t) {
	if (t == NULL) {
		return;
	}
	printf("%5d\t",t->data);
	preOrderWithRecursion(t->lchild);
	preOrderWithRecursion(t->rchild);
}
//中序遍历的递归算法
void inOrderWithRecursion(binaryTree *t) {
	if (t == NULL) {
		return;
	}
	
	inOrderWithRecursion(t->lchild);
	printf("%5d\t",t->data);
	inOrderWithRecursion(t->rchild);
}
//后序遍历的递归算法
void postOrderWithRecursion(binaryTree *t){
	if (t == NULL) {
		return;
	}
	
	postOrderWithRecursion(t->lchild);
	postOrderWithRecursion(t->rchild);
	printf("%5d\t",t->data);
}
//层次序的非递归遍历算法
void  levelOrderWithoutRecursion(binaryTree *t) {
	binaryTree *temp;
	pushElement(t);
	while (!emptyQueue()) {
		temp = popElement();
		printf("%5d\t", temp->data);
		if(temp->lchild) {
			pushElement(temp->lchild);
		}
		if(temp->rchild) {
			pushElement(temp->rchild);
		}
	}
}
//main方法 
int main()
{
	binaryTree *root;//创建根
	setNull();//制空栈
	root=creatBinaryTree();//创建二叉树:尝试输入:1 2 3 0 0 4 0 0 5 6 0 0 7 0 0
	printf("非递归前序遍历:\n");
	preOrderWithoutRecursion(root);
	printf("非递归中序遍历:\n");
	inOrderWithoutRecursion(root);
	printf("非递归后序遍历:\n");
	postOrderWithoutRecursion(root);
	printf("**********************************************************************");
	printf("\n"); 
	printf("递归前序遍历:\n");
	preOrderWithRecursion(root);
	printf("\n递归中序遍历:\n");
	inOrderWithRecursion(root);
	printf("\n递归后序遍历:\n");
	postOrderWithRecursion(root);
	printf("\n**********************************************************************");
	printf("\n层次序非递归遍历结果:\n");
	levelOrderWithoutRecursion(root); 
	return 0;
}

  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值