• 二叉树层次遍历


    题目描述

    编一个程序,读入用户输入的一串先序遍历字符串,根据输入建立一棵二叉树, 并输出该二叉树的层次遍历序列。层次遍历是指逐层访问,每一层又按从左到右的次序访问结点。

    输入

    输入包括1行字符串,长度不超过100。

    输出

    输出二叉树的层次遍历序列。每个结点先输出一个空格,然后再跟着输出结点的数据。

    样例输入 Copy
    12##3##
    
    样例输出 Copy
     1 2 3
    1. #include
    2. #include
    3. typedef int Status;
    4. typedef char ElemType;
    5. #define MaxSize 101
    6. #define OK 1
    7. #define ERROR -1
    8. #define OVERFLOW 0
    9. typedef struct BiTNode {
    10. ElemType data;
    11. struct BiTNode* lchild;
    12. struct BiTNode* rchild;
    13. } BTNode, * BiTree;
    14. typedef struct {
    15. BTNode data[MaxSize];
    16. int front, rear;
    17. } SqQueue;
    18. void InitQueue(SqQueue* qu) {
    19. qu->front = qu->rear = 0;
    20. }
    21. int QueueEmpty(SqQueue* qu) {
    22. return qu->front == qu->rear;
    23. }
    24. void enQueue(SqQueue* qu, BTNode* node) {
    25. if ((qu->rear + 1) % MaxSize == qu->front)
    26. return;
    27. qu->data[qu->rear] = *node;
    28. qu->rear = (qu->rear + 1) % MaxSize;
    29. }
    30. void deQueue(SqQueue* qu, BiTree* node) {
    31. if (qu->front == qu->rear)
    32. return;
    33. *node = &(qu->data[qu->front]);
    34. qu->front = (qu->front + 1) % MaxSize;
    35. }
    36. void LevelOrder(BiTree b) {
    37. if (!b)
    38. return;
    39. SqQueue qu;
    40. InitQueue(&qu);
    41. enQueue(&qu, b);
    42. while (!QueueEmpty(&qu)) {
    43. BiTree p;
    44. deQueue(&qu, &p);
    45. printf(" %c", p->data);
    46. if (p->lchild != NULL)
    47. enQueue(&qu, p->lchild);
    48. if (p->rchild != NULL)
    49. enQueue(&qu, p->rchild);
    50. }
    51. }
    52. void CreateBiTree(BiTree* T) {
    53. ElemType ch;
    54. scanf(" %c", &ch); // Add a space before %c to consume any whitespace characters including newline
    55. if (ch == '#')
    56. *T = NULL;
    57. else {
    58. if (!(*T = (BTNode*)malloc(sizeof(BTNode))))
    59. exit(OVERFLOW);
    60. (*T)->data = ch;
    61. CreateBiTree(&((*T)->lchild));
    62. CreateBiTree(&((*T)->rchild));
    63. }
    64. }
    65. void FreeBiTree(BiTree T) {
    66. if (T == NULL)
    67. return;
    68. FreeBiTree(T->lchild);
    69. FreeBiTree(T->rchild);
    70. free(T);
    71. }
    72. int main() {
    73. BiTree T = NULL;
    74. printf("Enter a preorder traversal string (length <= 100):\n");
    75. CreateBiTree(&T);
    76. printf("Level order traversal:\n");
    77. LevelOrder(T);
    78. printf("\n");
    79. FreeBiTree(T); // Free dynamically allocated memory
    80. return 0;
    81. }

    ```c
    #include
    #include
    ```
    这两行包含了标准输入输出和内存分配函数的头文件。

    ```c
    typedef int Status;
    typedef char ElemType;
    ```
    这里定义了两个类型别名,`Status` 和 `ElemType`,分别用于表示函数的状态和二叉树节点的数据类型。

    ```c
    #define MaxSize 101
    #define OK 1
    #define ERROR -1
    #define OVERFLOW 0
    ```
    这里定义了一些宏,用于指定队列的最大大小以及一些状态码,比如 `OK` 表示成功,`ERROR` 表示错误,`OVERFLOW` 表示内存溢出。

    ```c
    typedef struct BiTNode {
        ElemType data;
        struct BiTNode* lchild;
        struct BiTNode* rchild;
    } BTNode, * BiTree;
    ```
    这个结构体定义了二叉树的节点结构,包含了节点的数据以及左右子节点的指针。`BTNode` 是节点类型的别名,`BiTree` 是节点指针类型的别名。

    ```c
    typedef struct {
        BTNode data[MaxSize];
        int front, rear;
    } SqQueue;
    ```
    这个结构体定义了一个顺序队列,用于层序遍历时存储节点。它包含了一个数组用于存储节点,以及队列的前后指针。

    ```c
    void InitQueue(SqQueue* qu) {
        qu->front = qu->rear = 0;
    }
    ```
    这个函数用于初始化队列,将队列的前后指针都设置为0,表示队列为空。

    ```c
    int QueueEmpty(SqQueue* qu) {
        return qu->front == qu->rear;
    }
    ```
    这个函数用于判断队列是否为空,即前后指针是否相等。

    ```c
    void enQueue(SqQueue* qu, BTNode* node) {
        if ((qu->rear + 1) % MaxSize == qu->front)
            return;
        qu->data[qu->rear] = *node;
        qu->rear = (qu->rear + 1) % MaxSize;
    }
    ```
    这个函数用于入队操作,将节点加入队列。如果队列已满,则不进行操作。

    ```c
    void deQueue(SqQueue* qu, BiTree* node) {
        if (qu->front == qu->rear)
            return;
        *node = &(qu->data[qu->front]);
        qu->front = (qu->front + 1) % MaxSize;
    }
    ```
    这个函数用于出队操作,将队首节点出队,并将节点指针传出。如果队列为空,则不进行操作。

    ```c
    void LevelOrder(BiTree b) {
        if (!b)
            return;
        SqQueue qu;
        InitQueue(&qu);
        enQueue(&qu, b);
        while (!QueueEmpty(&qu)) {
            BiTree p;
            deQueue(&qu, &p);
            printf(" %c", p->data);
            if (p->lchild != NULL)
                enQueue(&qu, p->lchild);
            if (p->rchild != NULL)
                enQueue(&qu, p->rchild);
        }
    }
    ```
    这个函数实现了二叉树的层序遍历。它使用了顺序队列来辅助遍历,先将根节点入队,然后循环执行出队和入队操作,直到队列为空。在遍历过程中,打印每个节点的数据,并将其左右子节点入队。

    ```c
    void CreateBiTree(BiTree* T) {
        ElemType ch;
        scanf(" %c", &ch); // Add a space before %c to consume any whitespace characters including newline
        if (ch == '#')
            *T = NULL;
        else {
            if (!(*T = (BTNode*)malloc(sizeof(BTNode))))
                exit(OVERFLOW);
            (*T)->data = ch;
            CreateBiTree(&((*T)->lchild));
            CreateBiTree(&((*T)->rchild));
        }
    }
    ```
    这个函数用于根据用户输入的先序遍历字符串构建二叉树。用户输入时,'#' 表示空节点。函数递归地构建左右子树,并动态分配内存。

    ```c
    void FreeBiTree(BiTree T) {
        if (T == NULL)
            return;
        FreeBiTree(T->lchild);
        FreeBiTree(T->rchild);
        free(T);
    }
    ```
    这个函数用于释放动态分配的二叉树内存,通过递归遍历二叉树的所有节点,并释放每个节点的内存。

    ```c
    int main() {
        BiTree T = NULL;
        printf("Enter a preorder traversal string (length <= 100):\n");
        CreateBiTree(&T);
        printf("Level order traversal:\n");
        LevelOrder(T);
        printf("\n");
        FreeBiTree(T); // Free dynamically allocated memory
        return 0;
    }
    ```
    这个函数是程序的入口,主要完成以下几个任务:
    - 提示用户输入先序遍历字符串。
    - 调用 `CreateBiTree` 函数构建二叉树。
    - 调用 `LevelOrder` 函数进行层序遍历并打印结果。
    - 调用 `FreeBiTree` 函数释放动态分配的内存。
    - 返回0表示程序成功运行结束。
    ```

  • 相关阅读:
    ros使用catkin_make编译报错Could NOT find PY_em (missing: PY_EM)
    【C++面向对象】8. 继承
    KD树邻域搜索原理,一看就懂,不懂请扇我
    图解-虚拟机使用NAT方式连网
    Spring源码里开天辟地的五个Bean,再介绍一个学习方法
    Spring七天速成:入门必看(一)
    链动2+1模式 一秒教您扩充你自己的私域流量池
    新版jdk的keytool没有md5,怎么解决?
    【Java】传输层UDP
    王怀民:推动中国开源创新从参与融入到蓄势引领 | CCF开源说
  • 原文地址:https://blog.csdn.net/2301_80173477/article/details/138000604