2024王道408数据结构 P143 T4

2024王道408数据结构 P143 T4

思考过程

你说你爱我,尊嘟假嘟O.o

  1. 题目让我们倒着来层次遍历二叉树,自下而上从右到左,那我们就多用一个队列来把元素逆置。先自上而下去遍历二叉树,再入栈,最后再把元素出栈。

举个例子

  1. 假设二叉树长这个样子,那题目就是让我们输出G F E D C B A,我们先用一个指针p来指向根树的根,也就是例子中的A,请添加图片描述先把A元素入队。之后我们要把A入栈,既然要入栈就要判断队列是否为空,不为空再入栈。只要队列里面有元素我们就出队,每次只出队一个元素请添加图片描述
  2. 出队之后我们的指针p指向A,现在我们判断A是否有左右孩子,如果有的话直接入栈。比如上面这个例子,A的左右孩子分别是B和C,所以我们就把B和C都入栈请添加图片描述此时队又不为空,所以我们再出队入栈一个队首元素B,此时指针p是指向B结点的。请添加图片描述
  3. 接下来继续判断B是否有左孩子右孩子,如果有的话将他们入队,所以我们将D和E都入队,入完了之后将队首元素C出队入栈,指针指向C,再判断C是否有左右孩子,以此类推,这样队列就空了,栈里面就剩请添加图片描述然后我们全部出栈就完成了对二叉树的自下而上,从右往左的遍历。主要就是用队来放层次,用栈来输出。

代码过程

  1. 首先我们需要一个指针p,struct TreeNode *p = t;接下来判断树是否存在,如果存在的话就把树的根先入队EnQueue(q, p);
  2. 之后判断是否队空,队不空的话就出队入栈队首元素DeQueue(q,p);EnStack(s, p);,再判断这个队首元素有没有左右孩子,有的话就直接入队if(p->lchild)EnQueue(q, p);if(p->rchild)EnQueue(q, p);,之后再出队入栈一个队首元素,这样就完成了一个循环。
  3. 最后输出栈里面的所有元素,while (!StackEmpty(s) DeStack(s, p);这题就做完了。

完整代码

这题有很多栈和队列的代码,各位写题的时候可以不用写出来,我这里为了能运行所以都写出来了。

//
// Created by 黎圣  on 2023/8/9.
//
#include "iostream"
#define MAX 10
struct TreeNode
{
    char data;
    struct TreeNode *lchild, *rchild;
};
struct Stack
{
    struct TreeNode *data[MAX];
    int top;
};
struct Queue
{
    struct TreeNode *data[MAX];
    int f, r ,tag;
};
bool StackEmpty(Stack &s)
{
    if (s.top == -1)
        return true;
    return false;
}
bool StackOverflow(Stack &s)
{
    if (s.top == MAX - 1)
        return true;
    return false;
}
bool EnStack(Stack &s, struct TreeNode *&p)
{
    if (StackOverflow(s))
    {
        printf("栈满,入栈失败\n");
        return false;
    }
    else
    {
        s.data[++s.top] = p;
        return true;
    }
}
int DeStack(Stack &s, struct TreeNode *&p)
{
    if (StackEmpty(s))
    {
        printf("栈空,出栈失败\n");
        return false;
    }
    else
        p = s.data[s.top--];
}
bool QueueEmtpy(Queue &q)
{
    if (q.f == q.r && q.tag == 0)
        return true;
    return false;
}
bool QueueOverflow(Queue &q)
{
    if (q.f == q.r && q.tag == 1)
        return true;
    return false;
}
bool EnQueue(Queue &q, struct TreeNode *&p)
{
    if (QueueOverflow(q))
    {
        printf("队满,入队失败\n");
        return false;
    }
    else
    {
        q.data[q.r] = p;
        q.r = (q.r + 1) % MAX;
        q.tag = 1;
        return true;
    }
}
bool DeQueue(Queue &q, struct TreeNode *&p)
{
    if (QueueEmtpy(q))
    {
        printf("队空,出队失败\n");
        return false;
    }
    else
    {
        p = q.data[q.f];
        q.f = (q.f + 1) % MAX;
        q.tag = 0;
        return true;
    }
}
void CreateTree(struct TreeNode *&t)
{
    char ch = getchar();
    if (ch == '#')
        t = NULL;
    else
    {
        t = (struct TreeNode*)malloc(sizeof(struct TreeNode));
        t->data = ch;
        t->lchild = NULL;
        t->rchild = NULL;
        CreateTree(t->lchild);
        CreateTree(t->rchild);
    }
}
void ergodic(struct TreeNode *&t)
{
    Stack s;
    Queue q;
    struct TreeNode *p = t;
    if (t != NULL)
    {
        s.top = -1;
        q.f = 0, q.r = 0, q.tag = 0;
        EnQueue(q, p);
        while (!QueueEmtpy(q))
        {
            DeQueue(q, p);
            EnStack(s, p);
            if (p->lchild != NULL)
                EnQueue(q, p->lchild);
            if (p->rchild != NULL)
                EnQueue(q, p->rchild);
        }
        while (!StackEmpty(s))
        {
            DeStack(s, p);
            printf("%c ", p->data);
        }
    }
}
int main()
{
    //我举的例子:ABD##E##CF##G##
    struct TreeNode *t;
    CreateTree(t);
    ergodic(t);
    return 0;
}

最后感谢b站up主@吸血小金鱼,这题纯麻烦

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值