当前位置:   article > 正文

C语言数据结构七:二叉树非递归遍历_二叉树非递归遍历算法c语言

二叉树非递归遍历算法c语言

二叉树的非递归遍历,必须借助的辅助。必须采用栈的这种先进后出的特性。

算法实现思路:

  • 我们先将根节点压入栈中。然后往外弹出元素。直到栈中元素弹完为止。
  • 1、将根节点压入栈中。(但是压入栈中,并不知简单的将根节点压入栈中就完事,我们必须引入一个标记信息。Flag:标识这个节点第几次压入栈中。)(标识:每个结点都要往栈中压两次。第二次再弹出来时,我们取数据。第一次压入栈中,我们将其标注为FALSE,标注是否取值。)
  • 所有节点在第一次弹出时都是false。

重新第一步:

  • 第一步:将根节点压入栈中,将标志位只为FALSE
  • 第二步:启动while循环:循环条件:栈不为空。
    • 先从栈中弹出栈顶元素。判断元素的标志位:
      • 如果标志位为True则:
        • 该节点值弹出:出栈,然后当前本次循环结束。
    • 如果标志位为false则:

       

      • 将该节点的左子树和右子树压入栈中。(先判断是否为空)
      • 此时入栈就要由顺序要求了。如果想要先序遍历,那么就需要反序压入。确保从栈中弹出元素时,先根后左右。
      • 根节点是二次入栈,将该标志位置为True。
  • 继续执行循环:
    • A先出栈,然后是B,B为false,将左右节点压入栈中,将标志位改为True。
    • 先入B,然后再入C。然后结束本次循环。
    • 先弹出B,然后C的标识位只为True,然后压入DE。不断循环。

我们继续采用前面是用的栈的代码。 

  1. #pragma once
  2. #include<stdlib.h>
  3. #include<string.h>
  4. #ifdef __cplusplus
  5. extern "C"{
  6. #endif
  7. #define MAX 1024
  8. //顺序栈数据结构
  9. struct SStack
  10. {
  11. void *data[MAX]; //存放数据的数组
  12. int size;//栈中元素的个数
  13. };
  14. typedef void * SeqStack;
  15. //数组高下标的位置当做栈顶,因为不需要移动数组中的元素在插入和删除中
  16. //初始化
  17. SeqStack Init_SeqStack();
  18. //入栈
  19. void Push_SeqStack(SeqStack stack, void *data);
  20. //出栈
  21. void Pop_SeqStack(SeqStack stack);
  22. //获得栈顶元素
  23. void *Top_SeqStack(SeqStack stack);
  24. //获得栈的大小
  25. int Size_SeqStack(SeqStack stack);
  26. //销毁栈
  27. void Destroy_SeqStack(SeqStack stack);
  28. #ifdef __cplusplus
  29. }
  30. #endif

采用栈的辅助

  1. #include"SeqStack.h"
  2. //初始化
  3. SeqStack Init_SeqStack()
  4. {
  5. struct SStack *stack = malloc(sizeof(struct SStack));
  6. if (NULL == stack)
  7. {
  8. return NULL;
  9. }
  10. //memset(stack->data, 0, sizeof(struct SStack));
  11. stack->size = 0;
  12. for (int i = 0; i < MAX; ++i)
  13. {
  14. stack->data[i] = NULL;
  15. }
  16. return stack;
  17. }
  18. //入栈
  19. void Push_SeqStack(SeqStack stack, void *data)
  20. {
  21. if (NULL == stack)
  22. {
  23. return;
  24. }
  25. if (NULL == data)
  26. {
  27. return;
  28. }
  29. struct SStack *s = (struct SStack *)stack;
  30. if (s->size == MAX)
  31. {
  32. return;
  33. }
  34. s->data[s->size] = data;
  35. s->size++;
  36. }
  37. //出栈
  38. void Pop_SeqStack(SeqStack stack)
  39. {
  40. if (NULL == stack)
  41. {
  42. return;
  43. }
  44. struct SStack *s = (struct SStack *)stack;
  45. if (s->size == 0)
  46. {
  47. return;
  48. }
  49. s->data[s->size - 1] = NULL;
  50. s->size--;
  51. }
  52. //获得栈顶元素
  53. void *Top_SeqStack(SeqStack stack)
  54. {
  55. if (NULL == stack)
  56. {
  57. return NULL;
  58. }
  59. struct SStack *s = (struct SStack *)stack;
  60. if (s->size == 0)
  61. {
  62. return NULL;
  63. }
  64. return s->data[s->size - 1];
  65. }
  66. //获得栈的大小
  67. int Size_SeqStack(SeqStack stack)
  68. {
  69. if (NULL == stack)
  70. {
  71. return -1;
  72. }
  73. struct SStack *s = (struct SStack *)stack;
  74. return s->size;
  75. }
  76. //销毁栈
  77. void Destroy_SeqStack(SeqStack stack)
  78. {
  79. if (NULL == stack)
  80. {
  81. return;
  82. }
  83. free(stack);
  84. }

为了实现二叉树的非递归遍历:

节点结构体:除了节点,还需要一个标识位

  1. struct Info
  2. {
  3. struct BiNode *node;
  4. bool flag;
  5. };

 因为引入bool量,所以引用:<stdbool.h>

  1. struct BiNode
  2. {
  3. char ch;
  4. struct BiNode *lchild;
  5. struct BiNode *rchild;
  6. };

初始化根节点:返回根节点,然后输入为

  1. struct Info* createInfo(struct BiNode *node, bool flag)
  2. {
  3. struct Info *info = malloc(sizeof(struct Info));
  4. info->flag = flag;
  5. info->node = node;
  6. return info;
  7. }

初始化栈:

  1. void nonRecursion(struct BiNode *root)
  2. {
  3. //初始化栈
  4. SeqStack stack = Init_SeqStack();
  5. //先把根节点压入栈中
  6. Push_SeqStack(stack, createInfo(root, false));
  7. while (Size_SeqStack(stack) > 0)
  8. {
  9. //获得栈顶元素
  10. struct Info *info = (struct Info *)Top_SeqStack(stack);
  11. //弹出栈顶元素
  12. Pop_SeqStack(stack);
  13. if (info->flag)
  14. {
  15. printf("%c ",info->node->ch);
  16. free(info);
  17. continue;
  18. }
  19. // 这个地方的压栈顺序,就影响了后续的输出顺序。压入栈顺序不同,最后出栈顺序也不同。
  20. //将根节压入栈中
  21. info->flag = true;
  22. Push_SeqStack(stack, info);
  23. //将右子树压入栈中
  24. if (info->node->rchild != NULL)
  25. {
  26. Push_SeqStack(stack, createInfo(info->node->rchild, false));
  27. }
  28. //将左子树压入栈中
  29. if (info->node->lchild != NULL)
  30. {
  31. Push_SeqStack(stack, createInfo(info->node->lchild, false));
  32. }
  33. }
  34. //销毁栈
  35. Destroy_SeqStack(stack);
  36. }

 整体实现:

  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include<stdio.h>
  3. #include<string.h>
  4. #include<stdlib.h>
  5. #include<stdbool.h>
  6. #include"SeqStack.h"
  7. struct BiNode
  8. {
  9. char ch;
  10. struct BiNode *lchild;
  11. struct BiNode *rchild;
  12. };
  13. struct Info
  14. {
  15. struct BiNode *node;
  16. bool flag;
  17. };
  18. struct Info* createInfo(struct BiNode *node, bool flag)
  19. {
  20. struct Info *info = malloc(sizeof(struct Info));
  21. info->flag = flag;
  22. info->node = node;
  23. return info;
  24. }
  25. void nonRecursion(struct BiNode *root)
  26. {
  27. //初始化栈
  28. SeqStack stack = Init_SeqStack();
  29. //先把根节点压入栈中
  30. Push_SeqStack(stack, createInfo(root, false));
  31. while (Size_SeqStack(stack) > 0)
  32. {
  33. //获得栈顶元素
  34. struct Info *info = (struct Info *)Top_SeqStack(stack);
  35. //弹出栈顶元素
  36. Pop_SeqStack(stack);
  37. if (info->flag)
  38. {
  39. printf("%c ",info->node->ch);
  40. free(info);
  41. continue;
  42. }
  43. //将根节压入栈中
  44. info->flag = true;
  45. Push_SeqStack(stack, info);
  46. //将右子树压入栈中
  47. if (info->node->rchild != NULL)
  48. {
  49. Push_SeqStack(stack, createInfo(info->node->rchild, false));
  50. }
  51. //将左子树压入栈中
  52. if (info->node->lchild != NULL)
  53. {
  54. Push_SeqStack(stack, createInfo(info->node->lchild, false));
  55. }
  56. }
  57. //销毁栈
  58. Destroy_SeqStack(stack);
  59. }
  60. void test()
  61. {
  62. struct BiNode nodeA = { 'A', NULL, NULL };
  63. struct BiNode nodeB = { 'B', NULL, NULL };
  64. struct BiNode nodeC = { 'C', NULL, NULL };
  65. struct BiNode nodeD = { 'D', NULL, NULL };
  66. struct BiNode nodeE = { 'E', NULL, NULL };
  67. struct BiNode nodeF = { 'F', NULL, NULL };
  68. struct BiNode nodeG = { 'G', NULL, NULL };
  69. struct BiNode nodeH = { 'H', NULL, NULL };
  70. nodeA.lchild = &nodeB;
  71. nodeA.rchild = &nodeF;
  72. nodeB.rchild = &nodeC;
  73. nodeC.lchild = &nodeD;
  74. nodeC.rchild = &nodeE;
  75. nodeF.rchild = &nodeG;
  76. nodeG.lchild = &nodeH;
  77. nonRecursion(&nodeA);
  78. }
  79. int main(){
  80. test();
  81. system("pause");
  82. return EXIT_SUCCESS;
  83. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/903024
推荐阅读
相关标签
  

闽ICP备14008679号