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