二叉树的前序中序后序递归遍历和非递归遍历(c语言版本)

直接上代码,可以直接运行。

#include <stdio.h>
#include<string.h>
#include <stdlib.h>
#include <stdbool.h>
/**二叉树数据结构定义**/
struct treenode
{
    char val;
    struct treenode *left;
    struct treenode *right;
}treenode;

//建立二叉树
struct treenode* build_tree(char* s,int i)
{

    if(i>=strlen(s))return NULL;
    if(s[i]=='#')return NULL;
    //printf("%d\n",i);
    struct treenode* root=(struct treenode*)malloc(sizeof(treenode));
    root->val=s[i];
    if(2*i+1<strlen(s))root->left=build_tree(s,2*i+1);
    else root->left=NULL;
    if(2*i+2<strlen(s))root->right=build_tree(s,2*i+2);
    else root->right=NULL;
    return root;
}
//先根递归遍历
void preOrder(struct treenode* root)
{
    if(root==NULL)return ;
    printf("%c",root->val);
    if(root->left!=NULL)preOrder(root->left);
    if(root->right!=NULL)preOrder(root->right);
}
//中根递归遍历
void inOrder(struct treenode* root)
{
    if(root==NULL)return ;
    inOrder(root->left);
    printf("%c",root->val);
    inOrder(root->right);
}
//后根递归遍历
void postOrder(struct treenode* root)
{
    if(root==NULL)return ;
    postOrder(root->left);
    postOrder(root->right);
    printf("%c",root->val);
}
//先根非递归遍历
//ABC#DE#
void Pre1Order(struct treenode *bt)
{
    struct treenode **s;
	struct treenode *p;
	int top=-1;
	//创建栈;
	s=(struct treenode **)malloc((100+1)*sizeof(struct treenode *));
	//初始化栈;
	s[++top]=bt;
	//非递归前序遍历;
	while(top!=-1)
	{
		p=s[top--];
		printf("%c",p->val);    //栈的特点,先进后出;
		if(p->right)
			s[++top]=p->right;
		if(p->left)
			s[++top]=p->left;
	}
	free(s);
}

void In1Order(struct treenode *bt)
{
	struct treenode **s;
    struct treenode *p,*q;
    int top=-1;
	//创建栈;
	s=(struct treenode **)malloc((100+1)*sizeof(struct treenode *));
	//非递归中序遍历;
    if(bt)
    {
        while(bt)   //一直遍历左子树直到该结点的左孩子空为止;
        {
            s[++top]=bt;   //将所有左孩子存入栈中;
            bt=bt->left;     //指向下一个左子树;
        }
        while(top!=-1)  //栈空时结束循环;
        {
            p=s[top--];//刚开始将最p指向左下角的左孩子,并且移向该结点的父结点;
            printf("%c",p->val);  //输出左下角的结点;
            while(p->right)  //遍历移动后结点有没有右结点;
            {
                s[++top]=p->right;   //将这个结点的右子树入栈;
                q=p->right;		  //这个右子树结点赋给q;
                while(q->left)      //判断结点q有没有左子树;
                {
                    s[++top]=q->left;  //有左子树,将与这个结点相连的所有左子树都入栈;
                    q=q->left;
                }
                break;   //结束当前循环,回到第二个while循环继续刚才的步骤;
            }
        }
    }
}


void Post1Order(struct treenode *bt)
{
	struct treenode **s;
	struct treenode *p;
    int top=-1;
	//创建栈;
	s=(struct treenode **)malloc((100+1)*sizeof(struct treenode *));
	//非递归后序遍历;
    do
    {
        while(bt)     //一直遍历左子树直到该左子树的左孩子空为止;
        {
            s[++top]=bt;     //将所有左孩子存入栈中;
            bt=bt->left;   //指向下一个左子树;
        }
        p=NULL;
        while(top!=-1)
        {
            bt=s[top];
            if(bt->right==p)  //p:表示为null,或者右子节点被访问过了;
            {
                printf("%c",bt->val);   //输出结点数据域;
                top--;           //输出以后,top--;
                p=bt;  //p记录下刚刚访问的节点;
            }
            else
            {
                bt=bt->right;   //访问右子树结点;
                break;
            }
        }
    }while(top!=-1);
}



int main()
{
    char s[100]={0};
    gets(s);
    struct treenode* root=(struct treenode*)malloc(sizeof(struct treenode));
    root=build_tree(s,0);
    printf("递归遍历:\n");
    printf("先根 ");
    preOrder(root);
    printf("\n");

    printf("中根 ");
    inOrder(root);
    printf("\n");
    printf("后根 ");
    postOrder(root);
    printf("\n");
    printf("非递归遍历:\n");
    printf("先根 ");
    Pre1Order(root);
    printf("\n");
    printf("中根 ");
    In1Order(root);
    printf("\n");
    printf("后根 ");
    Post1Order(root);
    printf("\n");
    return 0;

}

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值