数据结构: 非递归先序创建二叉树及其先序,中序和后序遍历

非递归先序创建二叉树及其先序,中序和后序遍历:(C语言实现如下)

#include<stdio.h>
#include <stdlib.h>
#include <string.h>


#define MAXSIZE 100
typedef struct BTNode
{
    char data;
    struct BTNode *lchild, *rchild;
} BTNode;

BTNode* CreatBTNode(char *str);
void InOrder(BTNode *BT);
void PreOrder(BTNode *BT);
void PostOrder(BTNode *BT);

int main()
{
    BTNode* BT = NULL;
    char str[100] = "\0";
    printf("请输入先序序列(空结点用#代替):\n");
    gets(str);
    BT = CreatBTNode(str);
    printf("OK!");
    printf("\n非递归算法如下:\n");
    if(BT)
    {
        printf("\n中序序列:\n");
        InOrder(BT);
    }
    if(BT)
    {
        printf("\n先序序列:\n");
        PreOrder(BT);
    }
    if(BT)
    {
        printf("\n后序序列:\n");
        PostOrder(BT);
    }
    return 0;




}

void PostOrder(BTNode *BT)
{
    BTNode* st[MAXSIZE] = {NULL};//这里为了简化代码,用指针数组来构建栈的结构
    int top = -1;//栈顶指针,初始化为-1
    int st2[MAXSIZE] = {-1};//用于每个存放结点附带的标志位
    while(top != -1 || BT != NULL)//当栈为空并且二叉树的结点为空时跳出循环
    {
        if(BT != NULL)
        {
            st[++top] = BT;//当前结点进栈
            st2[top] = 0;//标志设为0代表将访问栈顶结点的左孩子
            BT = BT->lchild;//转向当前结点的左孩子
        }
        else if(st2[top] == 0)//已访问了栈顶结点的左孩子
        {
            st2[top] = 1;//标志设为1代表将访问栈顶结点的右孩子
            BT = st[top]->rchild;//转向当前结点的右孩子
        }
        else                   //栈顶结点的左右孩子都已访问完了
        {
            BT = st[top--];//栈顶结点出栈
            printf("%c", BT->data);//访问当前结点
            BT = NULL;
        }
    }
    printf("\n");
}


//中序遍历
void InOrder(BTNode *BT)
{
    BTNode* st[100] = {NULL};
    int top = -1;
    while(top != -1 || BT!= NULL)
    {
        if(BT)
        {
            st[++top] = BT;//进栈
            BT = BT->lchild;
        }
        else
        {
            BT = st[top--];//出栈
            printf("%c", BT->data);
            BT = BT->rchild;
        }
    }
    printf("\n");


}

//先序遍历
void PreOrder(BTNode *BT)
{
    BTNode* st[100] = {NULL};
    int top = -1;
    while(top != -1 || BT != NULL)
    {
        if(BT)
        {
            printf("%c", BT->data);
            st[++top] = BT;//进栈
            BT = BT->lchild;
        }
        else
        {
            BT = st[top--];//出栈
            BT = BT->rchild;
        }
    }
    printf("\n");


}


//用先序序列创建二叉树的伪代码树下
/*  1.先判断字符数组中的元素是否为空(也就是是否为#),
    若不为空,为结构体动态分配内存,再判断是否内存分配成功
    2.若成功,则将结点赋值,并将根结点进栈,再把标志设为左
    3.重复1,
    标志为左:给栈顶结点的左子树根结点赋值
    标志为右:给栈顶结点的右子树根结点赋值,栈顶结点出栈
    (代表栈顶结点的左右子树已经创建完毕)
    4.当前处理的结点进栈,将标志设为左
    5.下一个字符如果是"#",将标志设为右;如果前一个字符也是"#",则栈顶结点出栈
    (也就是说该栈顶顶结点没有孩子)
    6.重复3~5步,直到结束。*/

BTNode* CreatBTNode(char *str)
{
    BTNode* head = NULL;
    BTNode* p = NULL;
    BTNode* st[100] = {NULL};
    int top = -1;
    int flag = 0;
    int j = 0;
    while(str[j] != '\0')
    {

        if(str[j] !='#')
        {
            p = (BTNode*)malloc(sizeof(BTNode));
            if(!p)
            {
                printf("内存分配失败!\n");
                return NULL;
            }
            memset(p,0x00, sizeof(BTNode));
            p->data = str[j];
            if(head == NULL)
            {
                head = p;
            }
            else
            {
                switch(flag)
                {
                case 0:
                    st[top]->lchild = p;
                    break;
                case 1:
                    st[top]->rchild = p;
                    top--;
                    break;
                }

            }
            st[++top] = p;
            flag = 0;



        }
        else
        {
            flag = 1;
            if(str[j-1] == '#')
            {
                top--;
            }
        }
        j++;
    }
    return head;
}

大家如有什么问题可以提问!

猜你喜欢

转载自blog.csdn.net/weixin_41588502/article/details/80529950
今日推荐