非递归创建二叉树

来源:互联网 发布:mac截图不在桌面 编辑:程序博客网 时间:2024/06/05 16:05

非递归创建二叉树,其实我们如果学过回溯算法,它的理解是不是还要简单一些。创建一个节点,我们是不是要知道它的左孩子、右孩子是有还是没有,孩子下还有孩子。我们知道这样下去好想无法知道上面该怎样进行。也就是我们要知道下一步还要找到它的根节点。这样我们是不是要借助一个容器来保存节点。将上一级的根入栈,我这里又一个例子使用‘#’来进行判断是否进行下去(简单的就是它有没有该节点)。我是给大家一点思路:

一、来自我的老师讲解的,或是来自书本的:

TreeNodePtr CreateBitree()
{
   LinkQueue q;
   TreeNodePtr bt, p, R;
   char a, b, S;
   InitQueue(&q);
   bt=NULL;
   printf("请输入节点的双亲、节点及LR标记值:");
   scanf("%c", &a);
   scanf("%c", &b);
   scanf("%c", &S);
while (b!='#')
   {
p= (TreeNodePtr)malloc(sizeof(TreeNodePtr));
p->data= b;
p->Lch= NULL;
p->Rch= NULL;
 
if (a=='#')
{
bt= p;
EnQueue(&q, p);
//入队
}
else
{

GetHead_Q(q, &R);
//得到头队列到指针
while(R->data!= a)
{
 
DeQueue(&q, &R);
GetHead_Q(q, &R);
 
}
if (S=='L')
{
R->Lch= p;
}
else
{
 
R->Rch= p;
DeQueue(&q, &R);
 
}
EnQueue(&q, p);
}
printf("请输入节点的双亲、节点及LR标记值:");
scanf("%c", &a);
while(a =='\n') 
scanf("%c", &a); 
scanf("%c", &b);
scanf("%c", &S);
   }
   return bt;
}

该方法是明确的指出它的根节点,如果有同学需要这样完整的程序,我前面有些的Queue的代码,

二、上面的办法其实是很明了的,大家一看就知道是怎么回事。我还有其他的方法,就是把它要让输入的人认识到树的结构,再进行输入,例如a#bc#d输入表示为a---右孩子---b---左孩子----c(c的根是b)等:

实现方法为:

1、空间实现栈:

typedef char Elem;

typedef struct Node{

    Elem Node;

    structNode *lchild;

    structNode *rchild;

    

}Node;

#define InISize 20

#define AppSize 50

typedef struct Stack{

    int Capacity;

    Node*base;

    Node*top;

}Stack;

typedef struct queue{

    Node *rear;

    Node *front;

    int size;

}Queue;

void IniStack(Stack *s)

{

    s->base=(Node*)malloc(InISize*sizeof(Node));

    if(!s->base)

        return ;

    s->top=s->base;

    s->Capacity=InISize;

}

int EmptyStack(Stack *s)

{

    if(s->base==s->top)

    {

        return 1;

    }

    else

        return 2;

}

void ClearStack(Stack *s)

{

    s->top=s->base;

}

void Push(Stack *s,Node d)

{

    

    if(s->top-s->base>=s->Capacity)

    {

        s->base=(Node *)realloc(s->base,AppSize*sizeof(Node));

        if(!s->base)

            return ;

        s->top=s->base+s->Capacity;

        s->Capacity=AppSize+InISize;

    }

    *(s->top)=d;

    s->top++;

}

void pop(Stack *s,Node *D)

{

    if(s->top==s->base)

        return ;

    s->top--;

    *D=*(s->top);

}

void destroyStack(Stack *s)

{

    free(s->base);

    s->top=s->base;

    s->Capacity=0;

}

int StackSize(Stack *s)

{

    return (int)(s->top-s->base);

}

2、树的实现:

Node* CreateNode(char data)

{

    Node* temp = (Node*)malloc(sizeof(Node));

    temp->Node = data;

    temp->lchild =NULL;

    temp->rchild =NULL;

    return temp;

}


Node *NewBuildTree(char *str)

{

    Stack S;

    Node *bt=NULL,*temp,*root;

    IniStack(&S);

    if(*str=='\0')

    {

        printf("EmptyTree\n");

        returnNULL;

    }

    root=CreateNode(*str);

    bt=root;

    while(*str!='\0'){

        str++;

        if(*(str-1)!='#')

        {

            Push(&S, *bt);

            if(*str!='#')

            {

                temp=CreateNode(*str);

                bt->lchild=temp;

                bt=temp;

            }

            else

            {

                bt->lchild=NULL;

            }

        }

        if(*(str-1)=='#'&&EmptyStack(&S)==2)

        {

            pop(&S, bt);

            if(*str!='#')

            {

                temp=CreateNode(*str);

                bt->rchild=temp;

                bt=temp;

            }

            else

            {

                bt->rchild=NULL;

            }

        }

        

    }

    return root;

}

或是用

void CreateTreeNode(Node *tree)

{

    char data;

    Stack S;

    Node *p=tree;

    scanf("%c",&data);

    getchar();

    p=(Node*)malloc(sizeof(Node));

    p->Node=data;

    while(data!='#')

    {

        Push(&S, *p);

        p=p->lchild;

        scanf("%c",&data);

        getchar();

        if(data!='#')

        {

            p=(Node*)malloc(sizeof(Node));

            p->Node=data;

        }

        else

            while (data=='#'&&EmptyStack(&S)==2) {

                p=NULL;

                pop(&S, p);

                p=p->rchild;

                scanf("%c",&data);

                getchar();

                if(data!='#')

                {

                    p=(Node*)malloc(sizeof(Node));

                    p->Node=data;

                }

                else

                {

                    p=NULL;

                }

            }

        

    }

}

3、非递归实现--先序实现

void TreePreNonRecurie(Node *tree)

{

    Node *p=tree;

    Stack S;

    IniStack(&S);

    while (EmptyStack(&S)!=1||p) {

        if(p)

        {

            printf("%c",p->Node);

            Push(&S,*p);

            p=p->lchild;

        }

        else

        {

            p=malloc(sizeof(Node));

            pop(&S, p);

            p=p->rchild;

        }

    }

    printf("\n");

}

非递归中序实现:

void TreeNoorecuried(Node*tree)

{

    Node *p=tree;

    Stack S;

    IniStack(&S);

    while(EmptyStack(&S)!=1||p)

    {

        if(p)

        {

            Push(&S, *p);

            p=p->lchild;

        }

        else

        {

            p=malloc(sizeof(Node));

            pop(&S, p);

            printf("%c",p->Node);

            p=p->rchild;

        }

    }

    printf("\n");

}

非递归后续也是同理,要复杂一点就是要判断有没有点进入栈了还有打印了吗?:

测试案例:

希望各位前辈提出意见,学生谢谢!分享一个写的非常详细的二叉树遍历的前辈写的:http://www.jianshu.com/p/49c8cfd07410

原创粉丝点击