• 二叉树——遍历:按层次非递归遍历、先序非递归、先中后序递归遍历二叉树的链表结构【C语言,数据结构】(内含源代码)


      前言:

    本篇文章仅给出关于二叉树的部分代码,若想深入了解二叉树请查看我的其他文章

    因为本次实验二叉树考察的内容太多了,所以我把它拆分成了三个部分,分别是建立,处理,遍历三个板块,三篇文章可以在我的博客或专栏中找到。

    以下是链接

    二叉树递归总头文件:

    http://t.csdn.cn/Vxst3

    建立包含以下内容:

    http://t.csdn.cn/YxBdf

    二叉树结构,二叉树的三种建立。

    遍历包含以下内容:

    http://t.csdn.cn/RD8nQ

    按层次非递归遍历、先序非递归、先中后序递归遍历二叉树的链表结构

    处理包含以下内容:

    http://t.csdn.cn/K3k4y

    求二叉树的高度、叶节点数、单分支节点数、双分支节点数,交换左右子树

    目录

    前言:

    遍历时用到的打印函数:

    二叉树的递归遍历:

    先序遍历:

    中序遍历:

    后序遍历:

    二叉树的特殊遍历:

    按层次非递归遍历:

    先序非递归遍历二叉树:

    栈头文件:

    队列头文件:


    遍历时用到的打印函数:

    这个打印函数会作为一个函数指针出现在遍历函数中,作为遍历的输出手段

    1. Status print(TElemType e) {
    2. //打印方式
    3. printf("%c ", e);
    4. return OK;
    5. }

    二叉树的递归遍历:

    先序遍历

    1. Status TraverseBiTree_Pre(BiTree T, Status(*print)(TElemType)) {
    2. //先序遍历二叉树
    3. if(T) {
    4. if(print(T->data)) {
    5. if(TraverseBiTree_Pre(T->lchild, print)) {
    6. if(TraverseBiTree_Pre(T->rchild, print)) {
    7. return OK;
    8. }
    9. }
    10. }
    11. return ERROR;
    12. }
    13. return OK;
    14. }

    中序遍历:

    1. Status TraverseBiTree_In(BiTree T, Status(*print)(TElemType)) {
    2. //中序遍历二叉树
    3. if(T) {
    4. if(TraverseBiTree_In(T->lchild, print)) {
    5. if(print(T->data)) {
    6. if(TraverseBiTree_In(T->rchild, print)) {
    7. return OK;
    8. }
    9. }
    10. }
    11. return ERROR;
    12. }
    13. return OK;
    14. }

    后序遍历:

    1. Status TraverseBiTree_Post(BiTree T, Status(*print)(TElemType)) {
    2. //后序遍历二叉树
    3. if(T) {
    4. if(TraverseBiTree_In(T->lchild, print)) {
    5. if(TraverseBiTree_In(T->rchild, print)) {
    6. if(print(T->data)) {
    7. return OK;
    8. }
    9. }
    10. }
    11. return ERROR;
    12. }
    13. return OK;
    14. }

    二叉树的特殊遍历:

    按层次非递归遍历:

    这里需要用到队列,队列的头文件我会附在文章末

    1. typedef BiTree QElemType;
    2. #include "ArrayQueue.h"
    3. Status TraverseBiTree_Level(BiTree T, Status(*print)(TElemType)) {
    4. //层序遍历二叉树
    5. if(T) {
    6. ArrayQueue Q;
    7. InitQueue(&Q);
    8. EnQueue(&Q, T);
    9. while(!QueueEmpty(Q)) {
    10. DeQueue(&Q, &T);
    11. print(T->data);
    12. if(T->lchild) {
    13. EnQueue(&Q, T->lchild);
    14. }
    15. if(T->rchild) {
    16. EnQueue(&Q, T->rchild);
    17. }
    18. }
    19. }
    20. return OK;
    21. }

    先序非递归遍历二叉树

    这里需要用到栈,栈的头文件我会附在文章末

    1. typedef BiTree SElemType;
    2. #include "Stack.h"
    3. Status TraverseBiTree_NRPre(BiTree T, Status(*print)(TElemType)) {
    4. //非递归先序遍历二叉树
    5. if(T) {
    6. SqStack S;
    7. InitStack(&S);
    8. while(T || !StackEmpty(S)) {
    9. if(T) {
    10. Push(&S, T);
    11. print(T->data);
    12. T = T->lchild;
    13. } else {
    14. Pop(&S, &T);
    15. T = T->rchild;
    16. }
    17. }
    18. }
    19. return OK;
    20. }

    栈头文件:

    1. #include //头文件
    2. #include
    3. #include
    4. #include
    5. #include
    6. #define TRUE 1 //函数结果状态码
    7. #define FALSE 0
    8. #define ERROR 0
    9. #define OK 1
    10. #define EQUAL 1
    11. #define OVERFLOW -1
    12. #define INFEASIBLE -2
    13. #define STACK_INIT_SIZE 100 //存储空间初始分配量
    14. #define STACKINCREMENT 10 //存储空间分配增量
    15. #define LIST_INIT_SIZE 100 //顺序表存储空间的初始分配量
    16. #define LISTINCREMENT 10 //顺序表存储空间的分配增量
    17. typedef int Status; //Status 为函数返回值类型,其值为函数结果状态代码
    18. typedef struct { //栈的顺序存储表示
    19. SElemType *base; //栈构造之前和销毁之后,其值为NULL
    20. SElemType *top; //栈顶指针
    21. int stacksize; //当前已分配的存储空间
    22. } SqStack;
    23. Status InitStack(SqStack *); //栈初始化
    24. Status DestroyStack(SqStack *); //销毁栈
    25. Status StackEmpty(SqStack); //栈判空
    26. Status GetTop(SqStack, SElemType *); //取栈顶元素
    27. Status Push(SqStack *, SElemType); //入栈
    28. Status Pop(SqStack *, SElemType *); //出栈
    29. Status StackTraverse(SqStack); //遍历栈,输出每个数据元素
    30. Status InitStack(SqStack *S) {
    31. //构造一个空栈Ss
    32. S->base = (SElemType *)malloc(STACK_INIT_SIZE * sizeof(SElemType));
    33. if(!S->base) {
    34. //存储分配失败
    35. exit(OVERFLOW);
    36. }
    37. S->top = S->base;
    38. S->stacksize = STACK_INIT_SIZE;
    39. return OK;
    40. }//InitStack
    41. Status GetTop(SqStack S, SElemType *e) {
    42. //若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR
    43. if(S.top == S.base) {
    44. return ERROR;
    45. }
    46. *e = *(S.top - 1);
    47. return OK;
    48. }//GetTop
    49. Status Push(SqStack *S, SElemType e) {
    50. //插入元素e为新的栈顶元素
    51. if(S->top - S->base >= S->stacksize) {
    52. //栈满,追加存储空间
    53. S->base = (SElemType *)realloc(S->base, (S->stacksize + STACKINCREMENT) * sizeof(SElemType));
    54. if(!S->base) {
    55. //存储分配失败
    56. exit(OVERFLOW);
    57. }
    58. S->top = S->base + S->stacksize;
    59. S->stacksize += STACKINCREMENT;
    60. }
    61. *S->top++ = e;
    62. return OK;
    63. }//Push
    64. Status Pop(SqStack *S, SElemType *e) {
    65. //若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROE
    66. if(S->top == S->base) {
    67. return ERROR;
    68. }
    69. *e = *(--S->top);
    70. return OK;
    71. }//Pop
    72. Status DestoryStack(SqStack *S) {
    73. //销毁栈S
    74. if(S->base) {
    75. free(S->base);
    76. }
    77. S->top = S->base = NULL;
    78. return OK;
    79. }//DestroyStack
    80. //Status StackTraverse(SqStack S) {
    81. // //遍历栈,输出每一个数据元素
    82. // SElemType *p = S.base;
    83. // int i = 0;
    84. // if(S.base == S.top) {
    85. // printf("Stack is Empty.\n");
    86. // return OK;
    87. // }
    88. // while(p < S.top) {
    89. // printf("[%d:%d,%d]", ++i, p->i, p->j);
    90. // p++;
    91. // }
    92. // printf("\n");
    93. // return OK;
    94. //}//StackTraverse
    95. Status StackEmpty(SqStack S) {
    96. //栈判空
    97. if(S.base == S.top) {
    98. return OK;
    99. }
    100. return ERROR;
    101. }

    队列头文件:

    1. //#inclue
    2. //#include
    3. #include
    4. #define TRUE 1 //函数结果状态码
    5. #define FALSE 0
    6. #define OK 1
    7. #define ERROR 0
    8. #define OVERFLOW -1
    9. #define INFEASIBLE -2
    10. typedef int Status; //Status 为函数返回值类型,其值为函数结果状态代码
    11. typedef struct {
    12. QElemType *base; //初始化的动态分配存储空间
    13. int front; //队头指针
    14. int rear; //队尾指针
    15. int length; //队列总长度
    16. } ArrayQueue;
    17. Status InitQueue(ArrayQueue *); //构造一个空队列Q
    18. Status DestroyQueue(ArrayQueue *); //销毁队列Q,Q不再存在
    19. Status ClearQueue(ArrayQueue *); //将Q清为空队列
    20. Status QueueEmpty(ArrayQueue ); //若队列Q为空,则返回TRUE,否则返回FALSE
    21. int QueueLength(ArrayQueue ); //返回Q的元素个数,即为队列的长度
    22. Status GetHead(ArrayQueue, QElemType *); //若队列不为空,则用e返回Q的队头元素,并返回OK;头则返回ERROR
    23. Status EnQueue(ArrayQueue *, QElemType); //插入元素e为Q的新的队尾元素
    24. Status DeQueue(ArrayQueue *, QElemType *); //若队列不为空,则删除Q的队头元素,用e返回其值,并返回OK;否则返回ERROR;
    25. //Status QueueTraverse(ArrayQueue, visit()); //从队头到队尾依次对队列Q中的每一个元素调用visit()。一旦visit失败,则操作失败;
    26. Status InitQueue(ArrayQueue *Q) {
    27. //构造一个空队列Q
    28. Q->length = 100;
    29. Q->base = (QElemType *)malloc(Q->length * sizeof(QElemType));
    30. if(!Q->base) {
    31. exit(OVERFLOW);
    32. }
    33. Q->front = Q->rear = 0;
    34. return OK;
    35. }
    36. Status DestroyQueue(ArrayQueue *Q) {
    37. //销毁队列Q,Q不再存在
    38. free(Q->base);
    39. return OK;
    40. }
    41. Status QueueEmpty(ArrayQueue Q) {
    42. //若队列Q为空,则返回TRUE,否则返回FALSE
    43. if(Q.front == Q.rear) {
    44. return TRUE;
    45. }
    46. return FALSE;
    47. }
    48. int QueueLength(ArrayQueue Q) {
    49. //返回Q的元素个数,即为队列的长度
    50. return Q.rear - Q.front;
    51. }
    52. Status GetHead(ArrayQueue Q, QElemType *e) {
    53. //若队列不为空,则用e返回Q的队头元素,并返回OK;头则返回ERROR
    54. if(Q.front == Q.rear) {
    55. return ERROR;
    56. }
    57. *e = Q.base[Q.front];
    58. return OK;
    59. }
    60. Status EnQueue(ArrayQueue *Q, QElemType e) {
    61. //插入元素e为Q的新的队尾元素
    62. if(Q->rear == Q->length - 1) {
    63. //队列满
    64. Q->length += 100;
    65. Q->base = (QElemType *)realloc(Q->base, Q->length * sizeof(QElemType));
    66. }
    67. Q->base[Q->rear] = e;
    68. Q->rear++;
    69. return OK;
    70. }
    71. Status DeQueue(ArrayQueue *Q, QElemType *e) {
    72. //若队列不为空,则删除Q的队头元素,用e返回其值,并返回OK;
    73. //否则返回ERROR;
    74. if(Q->front == Q->rear) {
    75. return ERROR;
    76. }
    77. *e = Q->base[Q->front];
    78. Q->front++;
    79. return OK;
    80. }

  • 相关阅读:
    CSRF 002
    网络安全人才就业前景如何?
    Ansible原理和安装
    二、鼎捷T100月加权成本之基础数据设置
    【斗破年番】导演紧急删减第66集预告,陨落心炎事件要重演?
    Linux下找出吃内存的方法
    深度学习之基于Python+OpenCV(DNN)性别和年龄识别系统
    linux批量杀进程命令
    分类问题的评价指标
    Allegro铜皮动静态切换操作指导
  • 原文地址:https://blog.csdn.net/qq_62792553/article/details/128003678