拼题A 二叉树的非递归遍历

拼题A 二叉树的非递归遍历

题目描述:
本题要求用非递归的方法实现对给定二叉树的 3 种遍历。
函数接口定义:

void InorderTraversal( BinTree BT );
void PreorderTraversal( BinTree BT );
void PostorderTraversal( BinTree BT );

其中BinTree结构定义如下:

typedef struct TNode *Position;
typedef Position BinTree;
struct TNode{
    ElementType Data;
    BinTree Left;
    BinTree Right;
    int flag;
};

要求 3 个函数分别按照访问顺序打印出结点的内容,格式为一个空格跟着一个字符。
此外,裁判程序中给出了堆栈的全套操作,可以直接调用。
裁判测试程序样例:

#include <stdio.h>
#include <stdlib.h>
typedef enum { false, true } bool;

typedef char ElementType;
typedef struct TNode *Position;
typedef Position BinTree;
struct TNode{
    ElementType Data;
    BinTree Left;
    BinTree Right;
    int flag;
};

/*------堆栈的定义-------*/
typedef Position SElementType;
typedef struct SNode *PtrToSNode;
struct SNode {
	SElementType Data;
	PtrToSNode Next;
};
typedef PtrToSNode Stack;

/* 裁判实现,细节不表 */
Stack CreateStack();
bool IsEmpty( Stack S );
bool Push( Stack S, SElementType X );
SElementType Pop( Stack S ); /* 删除并仅返回S的栈顶元素 */
SElementType Peek( Stack S );/* 仅返回S的栈顶元素 */
/*----堆栈的定义结束-----*/

BinTree CreateBinTree(); /* 裁判实现,细节不表 */
void InorderTraversal( BinTree BT );
void PreorderTraversal( BinTree BT );
void PostorderTraversal( BinTree BT );

int main()
{
    BinTree BT = CreateBinTree();
    printf("Inorder:");    InorderTraversal(BT);    printf("\n");
    printf("Preorder:");   PreorderTraversal(BT);   printf("\n");
    printf("Postorder:");  PostorderTraversal(BT);  printf("\n");
    return 0;
}
/* 你的代码将被嵌在这里 */

输入样例:
如图
在这里插入图片描述
输出样例:
Inorder: D B E F A G H C I
Preorder: A B D F E C G H I
Postorder: D E F B H G I C A

其实这题用递归也能过hhhh,但是既然题目让用非递归,还是老老实实地用非递归写叭~~
前序和中序遍历看过浙大的慕课以后应该很容易就写出来了,但是后序遍历就要动点脑子辣~
难点在于根什么时候输出,观察一下后序遍历的特点可以发现,最先输出的一定是叶子结点,即左右子树都为空的结点,那么我们一旦输出了一个结点, 就让它的父结点的左或右子树(是左还是右要判断一下)为空,这样我们输出的条件就只需判断一下该结点的左右子树是不是都为空就行辣,当然,最开始我们要不停地遍历左子树~
可能说的不太清楚(表达能力太差啦555),还是看看代码吧~

void InorderTraversal( BinTree BT ) // 中序遍历
{
    BinTree T = BT;
    Stack S = CreateStack();
    while(T || !IsEmpty(S))
    {
        while(T)
        {
            Push(S, T);
            T = T->Left;
        }
        if(!IsEmpty(S))
        {
            T = Pop(S);
            printf(" %c", T->Data);
            T = T->Right;
        }
    }
}

void PreorderTraversal( BinTree BT ) // 前序遍历
{
    BinTree T = BT;
    Stack S = CreateStack();
    while(T || !IsEmpty(S))
    {
        while(T)
        {
            printf(" %c", T->Data);
            Push(S, T);
            T = T->Left;
        }
        if(!IsEmpty(S))
        {
            T = Pop(S);
            T = T->Right;
        }
    }
}

void PostorderTraversal( BinTree BT ) // 后序遍历
{
    BinTree T = BT;
    Stack S = CreateStack();
    while(T || !IsEmpty(S))
    {
        while(T)
        {
            Push(S, T);
            T = T->Left;
        }
        if(!IsEmpty(S))
        {
            T = Peek(S);
            if(T->Left == NULL && T->Right == NULL) // 叶结点
            {
                T = Pop(S);
                printf(" %c", T->Data);
                if(!IsEmpty(S))  // 记得判断一下栈是否为空,刚开始忘了结果一直段错误。。
                {
                    BinTree t = Peek(S);
                    // 判断是让左子树为空还是右子树为空
                    if(t->Left == T)
                        t->Left = NULL;
                    else if(t->Right == T)
                        t->Right = NULL;
                }
            }
            T = T->Right;
        }
    }
}

没仔细看题。。。。BinTree结构体里面竟然还有一个flag,,,可能后序遍历用一下这个flag会好写一些???但我也还是没想到怎么用这个flag。。。反正不用也能过hhhhh

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章