二叉树的非递归遍历

22 篇文章 0 订阅
18 篇文章 1 订阅

二叉树的建立与遍历操作
(1) 二叉树的建立
先序中序遍历建立二叉树:
二叉树前序遍历序列中,第一个元素总是树的根节点的值。中序遍历序列中,左子树的节点的值位于根节点的值的左边,右子树的节点的值位
于根节点的值的右边。
递归解法:
(1)如果前序遍历为空或中序遍历为空或节点个数小于等于0,返回NULL。
(2)创建根节点。前序遍历的第一个数据就是根节点的数据,在中序遍历中找到根节点的位置,可分别得知左子树和右子树的前序和中序遍
历序列,重建左右子树。

中序后序遍历建立二叉树:
二叉树中序遍历序列中,左子树的节点的值位于根节点的值的左边,右子树的节点的值位于根节点的值的右边。后序遍历序列中,左子树的节点的值位于右子树节点的值的左边,右子树的节点的值位于根节点的值的左边。

递归解法:
(1)如果中序遍历为空或后序遍历为空或节点个数小于等于0,返回NULL。
(2)创建根节点。后序遍历的最后一个数据就是根节点的数据,在中序遍历中找到根节点的位置,可分别得知左子树和右子树的中序和后序遍
历序列,重建左右子树。

(2) 二叉树的遍历
先序遍历:
a. 如果二叉树为空,空操作
b. 如果二叉树不为空,访问根节点,前序遍历左子树,前序遍历右子树
中序遍历:
a. 如果二叉树为空,空操作。
b. 如果二叉树不为空,中序遍历左子树,访问根节点,中序遍历右子树
后序遍历:
a.如果二叉树为空,空操作
b. 如果二叉树不为空,后序遍历左子树,后序遍历右子树,访问根节点
层序遍历:
相当于广度优先搜索,使用队列实现。
队列初始化,将根节点压入队列。当队列不为空,进行如下操作:弹出 一个节点,访问,若左子节点或右子节点不为空,将其压入队列。

#include"stdio.h"
#include"stdlib.h"

#define MAXSIZE 100 


typedef struct Node
{
        char data;
        struct Node* Lchild;
        struct Node* Rchild;
        struct Node* parent;    
}BiTNode,*BiTree;


typedef struct
{
    BiTree *base;
    BiTree *top;
    int stacksize;
} Stack;

int StackEmpty(Stack *s);
int InitStack(Stack *s)
{
    s->base = (BiTree*)malloc(sizeof(BiTree)*MAXSIZE);
    s->top = s->base;
    s->stacksize = MAXSIZE;
    return 1;
}
int Visitnode(char T)
{
        printf("%c",T);
        return 1;
}

int GetTop(Stack *s, BiTree *c)
{
    if (StackEmpty(s))
        return 0;
    *c = *(s->top - 1);
    return 1;
}

int StackEmpty(Stack *s)
{
    if (s->base == s->top)
        return 1;
    return 0;
}


int Push(Stack *s, BiTree c)
{

    if (s->top - s->base >= s->stacksize)
    {
        s->base = (BiTree*)realloc(s->base, sizeof(BiTree)*(s->stacksize + 10));
        s->stacksize = s->stacksize + 10;
    }

    *(s->top++) = c;
    return 1;
}


int Pop(Stack *s, BiTree *c)
{
    if (StackEmpty(s))
        return 0;
    *c = *(--s->top);
    return 1;
}

BiTree CreateBiTree(){
    char ch;
    BiTree T;
    scanf("%c",&ch);

    if(ch=='#') T=NULL;     
    else                    
    {
        T =(BiTree)malloc(sizeof(BiTNode));
        T->data = ch;
        T->Lchild = CreateBiTree();
        T->Rchild = CreateBiTree();

    }
    return T;
}
int InOrder(BiTree T)
{
    Stack *S;
    BiTree p = T;
    S = (Stack *)malloc(sizeof(Stack));
    InitStack(S);

    while (p || !StackEmpty(S))
    {

        if (p)
        {
            Push(S, p);
            p = p->Lchild;
        }

        else
        {
            Pop(S, &p);
            if (!Visitnode(p->data))
                return 0;
            p = p->Rchild;
        }
    }
    return 1;
 } 
 int PreOrder(BiTree T)
 {
     Stack *S;  
    BiTree p;
    S = (Stack*)malloc(sizeof(Stack));
    InitStack(S);
    Push(S, T); 
    while (!StackEmpty(S))
    {

        if (GetTop(S, &p) && p)
        {
            if (!Visitnode(p->data))
                return 0;
            Push(S, p->Lchild);
        }

        else
        {
            Pop(S, &p); 
            if (!StackEmpty(S))
            {
                Pop(S, &p);
                Push(S, p->Rchild);  
            }
        }
    }
    return 1;
 }
int PostOrder(BiTree T)
{
    Stack *S;
    BiTree p, pre=NULL;//pre指向已访问过的最后一个结点。
    S = (Stack*)malloc(sizeof(Stack));
    InitStack(S);
    Push(S, T);//根指针进栈

    while (!StackEmpty(S))
    {

        if (GetTop(S, &p) && p->Lchild && pre != p->Lchild && !(p->Rchild && pre == p->Rchild))
            Push(S, p->Lchild);

        else if (p->Rchild && pre != p->Rchild)
            Push(S, p->Rchild);

        else
        {
            Pop(S, &p);
            if (!Visitnode(p->data))
                return 0;
            pre = p;
        }
    }
    return 1;
}
int main()
 {
    BiTree T;
    int n=0;
    T = CreateBiTree();
    PreOrder(T);
     printf("\n");
    InOrder(T);
    printf("\n");
    PostOrder(T);

 }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

YULIU_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值