先序非递归创建二叉树

本文介绍了如何使用非递归的方法创建二叉树,通过栈实现先序遍历的方式。博客中提供了C语言实现的代码,包括创建二叉树的函数Creat_PreOrder_Formal和先序遍历输出的函数PreOrder。代码中详细解释了每个步骤,帮助读者理解非递归创建二叉树的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近在学习二叉树,想着想着就写了一些小片段程序来加深自己的印象,由此就按照自己的想法决定写个二叉树先序创建的代码,按着自己的一些积累和想法最终完成了。感觉还是不太好,希望各位大神指点一下//

#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#include<malloc.h>
#define MAXSIZE 100
typedef struct BiTree
{
    char data;
    struct BiTree *lchild, *rchild;
}BiTree;//定义二叉树结构体//
typedef struct SqStack
{
    BiTree *data[MAXSIZE];
    int Top;
}SqStack;//定义栈结构//
SqStack S;//定义全局变量栈//

int StackEmpty(SqStack S);//判空函数//
int StackEmpty(SqStack S)
{
    if (S.Top == -1)
        return 1;
    return 0;
}
void Push(SqStack &S, BiTree *p);//入栈操作//
void Push(SqStack &S, BiTree *p)
{
    if (S.Top != MAXSIZE - 1)
        S.data[++S.Top] = p;
    else
        printf("Wrong!\n");
}
void Pop(SqStack &, BiTree *&);//出栈操作//
void Pop(SqStack &S, BiTree *&p)
{
    if (!StackEmpty(S))
        p = S.data[S.Top--];
    else
        printf("Wrong!\n");
}
void PreOrder (BiTree *&);//先序遍历递归输出算法//
void PreOrder (BiTree *& T)
{
    if (T == NULL)
        return ;
    printf("%c", T->data);
    PreOrder(T->lchild);
    PreOrder(T->rchild);
    
}

void Creat_PreOrder_Formal(BiTree *&);
void Creat_PreOrder_Formal(BiTree *&T)
{
    char ch,clear;//获取输入和消除多于字符//
    BiTree *q, *p,*pre;//这里想来想去还是需要三个指针,有想法的大神可以说说看//
    ch = getchar();
    while (ch != '#' || !StackEmpty(S))//输入非结束符或者栈非空时循环//
    {
        while((clear = getchar()) != 0 && clear != '\n' )
            continue;//消除多于字符//
        p = (BiTree *) malloc (sizeof (BiTree)*1);
        if (ch != '#')
        {
            if (T == NULL)//当首结点不存在时,将p结点赋予给首结点//
                q = T = p;
            else if (q == NULL)
                pre->rchild = p;

/*注意此处,考虑最后一个结点,此时某个小范围内左子树必定已经创建,则我们弹出上一个结点,我们知道,最后一个结点的左右子树在没有开始创建右子树时必定两边都是NULL,此时,我们可以利用q = 弹出结点的右子树(其为空,即此时q = NULL),进行左子树创建完毕后右子树创建的标志*/
            else
                q->lchild = p;

/*由于我们左子树没有创建完毕,此时q = p !=NULL,由此我们可以与上面的else if (q == NULL)形成对比,此时可以循环创建左子树*/ 
            q = p;  

 //注意,在else if 结束之后,我们可以认为右子树首个结点已经形成一个新树,由此可以接着进行以下代码的复用操作//
            p->data = ch;
            p->lchild = p->rchild = NULL;
            Push(S,p);    
        }
        else if (ch == '#' && !StackEmpty(S))//此时输入为结束符号,且栈非空//
        {
            Pop(S,pre);//栈弹出且有pre指向//
            q = pre->rchild;//q指向其右结点,必为空,也是上面else if 的判断来源//
        }
        ch = getchar();
        }
}
int main(void)//主函数//
{
    BiTree *T;
    T=NULL;
    S.Top = -1;
    Creat_PreOrder_Formal(T);
    PreOrder(T);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值