数据结构 C 代码 6.x: 自己建栈实现二叉树遍历

本文介绍了如何使用栈和队列非递归地实现二叉树的先序、中序和后序遍历。潘佳豪通过自定义栈和队列结构,展示了复杂条件下的后序遍历实现,而莫峦奇则利用先序遍历的思路,通过栈实现后序遍历。两篇文章都强调了问题转换的重要性,并提供了完整的C++代码示例。
摘要由CSDN通过智能技术生成

本贴为《数据结构》课程服务.

1. 主要内容

  1. 二叉树的先序、中序、后序遍历.
  2. 不准用递归.

2. 代码

2.1 潘佳豪

  1. 自己写栈, 真-不偷懒.
  2. 后序遍历有复杂的条件, 还有 while 循环的嵌套, 功力深厚.
  3. 居然还用文本在程序里画一棵树, 必成大器啊!
#include <iostream>
#include <malloc.h>
using namespace std;
#define MAXSIZE 1000

typedef int ElemType;

typedef struct TNode
{
    ElemType data;
    TNode *left;
    TNode *right;
} TNode,*Tree;

typedef struct Queue
{
    TNode *data[MAXSIZE];
    int front;
    int rear;
} queue;

typedef struct Stack
{
    TNode *data[MAXSIZE];
    int top;
} stack;

void BuildTree(Tree &root,int &index);

void InitQueue(queue *q);
void EnQueue(queue *q, Tree data);
void DeQueue(queue *q, Tree &data);
bool QueueEmpty(queue *q);
void BFP(Tree root);

void InitStack(stack *s);
void Push(stack *s, Tree data);
void Pop(stack *s, Tree &data);
Tree Top(stack *s);
bool StackEmpty(stack *s);
void PreOrder(Tree root);
void InOrder(Tree root);
void PostOrder(Tree root);

int main()
{
    Tree tree;
    int index = -1;
    BuildTree(tree,index);
    cout<<"构建的树:"<<endl
        <<"1            2 "<<endl
        <<"2        4       0 "<<endl
        <<"3     5   -1    7    8 "<<endl
        <<"4  -1  3      6 -1 -1 -1 "<<endl
        <<"5    -1 -1  -1 -1 "<<endl<<endl;
    //层级遍历
    cout<<"层级遍历的结果;";
    BFP(tree);
    //先序遍历
    cout<<"先序遍历的结果:";
    PreOrder(tree);
    //中序遍历
    cout<<"中序遍历的结果:";
    InOrder(tree);
    //后序遍历
    cout<<"后序遍历的结果:";
    PostOrder(tree);

    return 0;
}

//
//构建树
//             2
//         4       0
//      5   -1    7    8
//   -1  3      6 -1 -1 -1
//     -1 -1  -1 -1
void BuildTree(Tree &root,int &index)
{
    index++;
    ElemType temp[] = {2,4,5,-1,3,-1,-1,-1,0,7,6,-1,-1,-1,8,-1,-1};
    if(temp[index] == -1)
    {
        root = NULL;
        return;
    }
    else
    {
        root = (TNode*)malloc(sizeof(TNode));
        root->data = temp[index];
        BuildTree(root->left,index);
        BuildTree(root->right,index);
    }
}

//
//队列
//
void InitQueue(queue *q)
{
    q->rear = 0;
    q->front = 0;
}

void EnQueue(queue *q, Tree data)
{
    if((q->rear + 1) % MAXSIZE == q->front)
    {
        return;
    }
    q->data[q->rear++] = data;
    q->rear %= MAXSIZE;
}

void DeQueue(queue *q, Tree &data)
{
    if(q->rear == q->front)
    {
        return;
    }
    data = q->data[q->front++];
    q->front %= MAXSIZE;
}

bool QueueEmpty(queue *q)
{
    return q->front == q->rear;
}

void BFP(Tree root)
{
    queue q;
    InitQueue(&q);
    EnQueue(&q,root);
    while (!QueueEmpty(&q))
    {
        Tree temp;
        DeQueue(&q,temp);
        cout<<temp->data<<" ";
        if(temp->left) EnQueue(&q,temp->left);
        if(temp->right) EnQueue(&q,temp->right);
    }
    cout<<endl<<endl;
}

//
//栈
//
void InitStack(stack *s)
{
    s->top = 0;
}

void Push(stack *s, Tree data)
{
    if(s->top >= MAXSIZE)
    {
        return;
    }
    s->data[s->top++] = data;
}

void Pop(stack *s, Tree &data)
{
    if(s->top == 0)
    {
        return;
    }
    data = s->data[--s->top];
}

Tree Top(stack *s)
{
    return s->data[s->top-1];
}

bool StackEmpty(stack *s)
{
    return s->top == 0;
}

void PreOrder(Tree root)
{
    stack s;
    InitStack(&s);
    Tree temp = root;
    while(!StackEmpty(&s) || temp)
    {
        if(temp)
        {
            cout<<temp->data<<" ";
            Push(&s,temp);
            temp = temp->left;
        }
        else
        {
            Pop(&s,temp);
            temp = temp->right;
        }
    }
    cout<<endl<<endl;
}

void InOrder(Tree root)
{
    stack s;
    InitStack(&s);
    Tree temp = root;
    while(!StackEmpty(&s) || temp)
    {
        if(temp)
        {
            Push(&s,temp);
            temp = temp->left;
        }
        else
        {
            Pop(&s,temp);
            cout<<temp->data<<" ";
            temp = temp->right;
        }
    }
    cout<<endl<<endl;
}

void PostOrder(Tree root)
{
    stack s;
    InitStack(&s);
    Push(&s,root);
    Tree temp;
    Tree lastpop = NULL;
    while(!StackEmpty(&s))
    {
        while(Top(&s)->left)
        {
            Push(&s,Top(&s)->left);
        }
        while(!StackEmpty(&s))
        {
            if(lastpop == Top(&s)->right || Top(&s)->right == NULL)
            {
                cout<<Top(&s)->data<<" ";
                lastpop = Top(&s);
                Pop(&s,temp);
            }
            else if(Top(&s)->right != NULL)
            {
                Push(&s, Top(&s)->right);
                break;
            }
        }
    }
    cout<<endl<<endl;
}

2.2 莫峦奇

后序遍历是"左右中",把左右互换就是"右左中", 逆序即为"中左右" (先序). 用这种方式, 可以使用先序遍历的相同方式来实现它. 唯一的区别就是需要使用一个栈, 逆序输出. 问题的转换是多么地重要!

#include<iostream>
#include<stack>
using namespace std;

//二叉树数据结构
typedef struct TreeNode
{
    char data;
    struct TreeNode *Leftchild;
    struct TreeNode *Rightchild;
    TreeNode(char c)
    {
        data=c;
        Leftchild=NULL;
        Rightchild=NULL;
    }
} TreeNode,*Tree;

//创建二叉树
void CreateTree(Tree &p)
{
    char c;
    cin>>c;
    if(c=='#') p=NULL;
    else
    {
        p=new TreeNode(c);
        cout<<"请输入"<<p->data<<"的左子树: ";
        CreateTree(p->Leftchild);
        cout<<"请输入"<<p->data<<"的右子树: ";
        CreateTree(p->Rightchild);
    }
}

//先序遍历
void PreOrder(Tree &T)
{
    stack<Tree> S;
    Tree p=T;
    while(p||!S.empty())
    {
        if(p)
        {
            cout<<p->data<<" ";
            S.push(p);
            p=p->Leftchild;
        }
        else
        {
            p=S.top()->Rightchild;
            S.pop();
        }
    }
}

//中序遍历
void InOrder(Tree &T)
{
    stack<Tree> S;
    Tree p=T;
    while(p||!S.empty())
    {
        if(p)
        {
            S.push(p);
            p=p->Leftchild;
        }
        else
        {
            p=S.top();
            cout<<p->data<<" ";
            p=p->Rightchild;
            S.pop();
        }
    }
}

//后序遍历
void PostOrder(Tree &T)
{
    Tree p=T;
    stack<Tree> S;
    stack<char> SS;
    while(p||!S.empty())
    {
        if(p)
        {
            SS.push(p->data);
            S.push(p);
            p=p->Rightchild;
        }
        else
        {
            p=S.top()->Leftchild;
            S.pop();
        }
    }
    while(!SS.empty())
    {
        cout<<SS.top()<<" ";
        SS.pop();
    }
}

int main()
{
    Tree p=NULL;
    cout<<"创建二叉树,请输入根节点(#表示节点为空): ";
    CreateTree(p);
    cout<<"先序遍历: ";
    PreOrder(p);
    cout<<endl;
    cout<<"中序遍历: ";
    InOrder(p);
    cout<<endl;
    cout<<"后序遍历: ";
    PostOrder(p);
    return 0;
}
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值