二叉树的遍历(非递归写法)

 

// 二叉树的遍历(非递归算法)

#include <stdio.h>
#include <malloc.h>
#include <stdbool.h>

typedef struct BiTNode
{
    int data;
    struct BiTNode *lchild, *rchild; // 存储二叉树的左孩子和右孩子
} BiTNode, *BiTree;

void createTree(BiTree &T) 
{
    T = (BiTree)malloc(sizeof(BiTNode));
    T->data = 1;

    T->lchild = (BiTNode *)malloc(sizeof(BiTNode));
    T->lchild->data = 2;

    T->lchild->lchild = (BiTNode *)malloc(sizeof(BiTNode));
    T->lchild->lchild->data = 4;
    T->lchild->lchild->lchild = NULL;
    T->lchild->lchild->rchild = NULL;

    T->lchild->rchild = (BiTNode *)malloc(sizeof(BiTNode));
    T->lchild->rchild->data = 5;

    T->lchild->rchild->lchild = (BiTNode *)malloc(sizeof(BiTNode));
    T->lchild->rchild->lchild->data = 7;
    T->lchild->rchild->lchild->lchild = NULL;
    T->lchild->rchild->lchild->rchild = NULL;

    T->lchild->rchild->rchild = (BiTNode *)malloc(sizeof(BiTNode));
    T->lchild->rchild->rchild->data = 8;
    T->lchild->rchild->rchild->lchild = NULL;
    T->lchild->rchild->rchild->rchild = NULL;

    T->rchild = (BiTNode *)malloc(sizeof(BiTNode));
    T->rchild->data = 3;
    T->rchild->lchild = NULL;

    T->rchild->rchild = (BiTNode *)malloc(sizeof(BiTNode));
    T->rchild->rchild->data = 6;
    T->rchild->rchild->lchild = NULL;
    T->rchild->rchild->rchild = NULL;
}

typedef struct SNode
{
    BiTree data; // 压入栈内的是BiTree型数据(即树的节点)
    struct SNode *next;
} SNode, *LinkStack;
// 栈的主要操作是在栈顶进行插入和删除,所以将链表的头部看为栈顶最合适
bool initLinkStack(LinkStack &S) // 链表初始化,将头指针所在的地址传进来
{
    S = NULL; // 头指针应该指向栈顶,所以初始化赋为NULL
    return true;
}

void Push(LinkStack &S, BiTree value) // 入栈操作
{
    SNode *p;
    p = (SNode *)malloc(sizeof(SNode));
    p->next = S; // 链表的头部为头指针
    p->data = value;
    S = p;
}

bool isEmpty(LinkStack S) // 判断栈是否为空
{
    if (S == NULL)
    {
        return true;
    }
    else
    {
        return false;
    }
}

bool Pop(LinkStack &S, BiTree &e) // 出栈操作
{
    if (S == NULL)
    {
        return false;
    }
    else
    {
        e = S->data;
        SNode *q; // 存储删除的节点来进行释放
        q = S;
        S = S->next;
        free(q);
        return true;
    }
}

void InitTree(BiTree &root)
{
    root = (BiTNode *)malloc(sizeof(BiTNode));
    root->data = -1;
    root->lchild = NULL;
    root->rchild = NULL;
}

void visit(BiTNode *T) // 访问函数
{
    printf("%d ", T->data);
}

void InOrder2(BiTree T) // 中序遍历
{
    LinkStack S;
    initLinkStack(S);
    BiTree p = T;            // p是遍历指针
    while (p || !isEmpty(S)) // 用或运算来进行判定
    {
        if (p)
        {
            Push(S, p); // 当前节点入栈
            p = p->lchild;
        }
        else
        {
            Pop(S, p);
            visit(p);
            p = p->rchild;
        }
    }
}

void PreOrder2(BiTree T) // 先序遍历
{
    LinkStack S;
    initLinkStack(S);
    BiTree p = T;
    while (p || !isEmpty(S))
    {
        if (p)
        {
            visit(p);
            Push(S, p);
            p = p->lchild;
        }
        else
        {
            Pop(S, p);
            p = p->rchild;
        }
    }
}

int main()
{
    BiTree Tree;
    createTree(Tree);
    printf("PreOrder2 : ");
    PreOrder2(Tree);
    printf("\n");
    printf("InOrder2 : ");
    InOrder2(Tree);
    printf("\n");
    return 0;
}

 

posted @ 2023-04-25 11:25  正方形的被子  阅读(23)  评论(0)    收藏  举报