数据结构习题: 建立广义表表示的树 并 层序输出

题目描述:

【问题描述】
 给定一颗二叉树,要求从下至上按层遍历二叉树,每层的访问顺序是从左到右,每一层单独输出一行。

【输入形式】
 广义表表示的二叉树,结点元素类型为整型,且都大于0,例如:1( 2( 3 ( 4, 5 ) ), 6( 7, 8( 9, 10 ) ) )

【输出形式】
 从下至上,打印每一层的结点元素值,元素间以空格隔开。每层的访问顺序是从左到右,每一层单独输出一行。

【样例输入】
 1(2(3(4,5)),6(7,8(9,10))),字符串内没有空格

【样例输出】
 4 5 9 10
 3 7 8
 2 6
 1

【样例说明】

【评分标准】
 本题目主要考察两个知识点:
 1.创建二叉树存储结构
 2.按层次遍历二叉树的算法

题目思路:

  • 这个题开始看的时候有点懵,因为这个是广义表建立二叉树,我是如下处理:
  1. 如果遇到了"(",说明要对这个结点的左子树进行创建
  2. 如果遇到了")", 说明要对这个结点的父结点进行操作
  3. 如果遇到了",",说明已近创建好了左结点(即现在的T指向的是左结点),要对T的父结点的右结点进行创建

因此可以很清楚的想到可以使用手动创建的堆栈(事实上我也使用过递归,但是递归写出的代码有点麻烦)

  • 对于从最后一层进行输出,我们也可以想到要使用层序遍历,但是如何修改层序遍历的代码来进行从最后一层网上输出呢?
  1. 我使用了一个队列 (层序遍历的基础),但是是先入右结点,再入左结点,并且记录每个结点的层次
  2. 之后对这个队列从后往前遍历 (这就解释了为什么需要先入右结点再入左结点)[因为这样会在队列从后往前遍历的时候先遍历树的左结点,再遍历右结点],对于相同层次的结点输出在一行,不同的则换行输出。

代码:

#include <stdio.h>
#include <stdlib.h>

typedef struct tree {
    int data;
    struct tree* lchild;
    struct tree* rchild;
}*Ptree;

typedef struct quee {
    Ptree data[100];
    int lay[100];
    int num;
    int rear, front;
}*Pquee;

typedef struct stack {
    Ptree data[100];
    int rear;
}*Pstack;

void in(Pstack s, Ptree T) {
    s->data[s->rear++] = T;
}

void pop(Pstack s, Ptree& T) {
    T = s->data[--s->rear];
}

void creat(Ptree& T, Pstack& s, char string[], int& i) {  // 1(2(3(4,5)),6(7,8(9,10)))
    T = (Ptree)malloc(sizeof(struct tree));
    T->lchild = NULL;   T->rchild = NULL;
    while (string[i] != '\0') {
        if (string[i] >= '0' && string[i] <= '9') {
            int num[10], n = 0;
            while (string[i] >= '0' && string[i] <= '9') {
                num[n++] = string[i] - '0';
                i++;  // 退出循环后i指向的为符号不是数字
            }
            int NUM = 0;
            for (int j = n; j > 0; j--) {
                int jiec = 1;
                for (int j1 = 1; j1 < j; j1++) {
                    jiec *= 10;
                }
                NUM += num[n - j] * jiec;
            }
            // printf("NUM = %d\n", NUM);
                //T = (Ptree)malloc(sizeof(struct tree));
                //T->lchild = NULL;   T->rchild = NULL;
            T->data = NUM;
            in(s, T);
        }
        // printf("string%d = %c\n", i, string[i]);

        if (string[i] == '(') {
            i = i + 1;
            T->lchild = (Ptree)malloc(sizeof(struct tree));
            T->lchild->lchild = NULL;   T->lchild->rchild = NULL;
            T = T->lchild;
        }
        if (string[i] == ')') {
            i = i + 1;
            pop(s, T);
            T = s->data[s->rear - 1];
        }
        if (string[i] == ',') {
            i = i + 1;
            pop(s, T);
            T = s->data[s->rear - 1];
            T->rchild = (Ptree)malloc(sizeof(struct tree));
            T->rchild->lchild = NULL;   T->rchild->rchild = NULL;
            T = T->rchild;
        }
    }
}

void print(Ptree T, Pquee q) {
    Ptree j = NULL;
    q->lay[q->rear] = 0;
    q->data[q->rear++] = T;
    int layer;
    while (q->front != q->rear) {
        layer = q->lay[q->front];
        j = q->data[q->front++];
        // 先入右结点
        if (j->rchild) {
            // printf("rch\n");
            q->lay[q->rear] = layer + 1;
            q->data[q->rear++] = j->rchild;
        }
        if (j->lchild) {
            // printf("lch\n");
            q->lay[q->rear] = layer + 1;
            q->data[q->rear++] = j->lchild;
        }
    }
    layer = q->lay[q->rear - 1];
    // printf("layer %d\n", layer);
    for (int i = q->rear - 1; i >= 0;) {
        // printf("lay[%d] i = %d\n", q->lay[i], i);
        if (q->lay[i] == layer) {
            printf("%d ", q->data[i]->data);
            i--;
        }
        else {
            printf("\n");
            layer--;
        }
    }
}

int main() {
    char string [100];
    scanf("%s", string);
    Pquee q = (Pquee)malloc(sizeof(struct quee));
    Pstack s = (Pstack)malloc(sizeof(struct stack));
    s->rear = 0;
    q->front = 0; q->rear = 0; q->num = 0;
    Ptree T = (Ptree)malloc(sizeof(struct tree));
    T->lchild = NULL;   T->rchild = NULL;
    int i = 0;
    creat(T->lchild, s, string, i);
    print(T->lchild, q);
    return 0;
}

运行结果:

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值