• 二叉树中的层遍历


    层遍历:从上到下、从左到右,如图所示:

    图示为举例进行层遍历顺序


    以上图为例,进行分析用栈还是队列

    • 如果用: 先进后出,想要输出顺序为先出左孩子后出右孩子的话,需要先进右后进左。

            入栈顺序:根 右 左 //必须通过根节点去保存左右孩子

            出栈:栈顶元素  //也就是后面入进来的先出

    • 举例上面的树图进行思路演绎:

            入栈:a

            出:a

            入:c b

            出:b

            入:c e d 

    那么问题来了:此时应该遍历c 但是c被压在栈底出不来,只能先访问d和e,所以无法用栈进行层次遍历,只能用队列进行遍历

    • 队:判断队列是否为空,不为空时出队顺序为先出队头

               入队顺序:根节点、左孩子、右孩子

               出队顺序:出队头元素

    • 步骤:

            ① 将根节点入队 

            ② 判断树是否为空,不为空,则队头元素进行入出队

            ③ 将刚出队元素的左右孩子进行入队

            ④ 将①②③循环,直至队列为空时,停止

    • 举例上面的树图进行思路演绎:

    (说明:灰色字母是已经出队元素,下划线代表目前队尾元素,蓝色是刚入队元素)

            入队:a   //首先判断树是否为空,不为空,则入树根a

            出队:a  //队头元素

            入:a b c  //先入a的左孩子b,再入a的右孩子c

            出:b   //队头元素

            入:a b c d e  //c还未出队所以还在,然后入b的左右孩子de

            出:c  //队头元素

            入:a b c d e f g  //de还未出队所以还在,然后入c的左右孩子fg

            出:d e f   //出队头元素d,d无左右孩子,继续出队头元素e,e无左右孩子,继续出队头元素f

            入: g  h  //入f的左右孩子gh

            出:g h  //出队头元素g,g无左右孩子,继续出队头元素h

            此时数组为空,说明入队的数据均已出队,所有节点访问完毕

    伪代码:

     代码:

    1. typedef struct node
    2. {
    3. char value;//当前节点值
    4. struct node* left;//指向当前节点左孩子指针
    5. struct node* right;//指向当前节点右孩子指针
    6. }Node;
    7. //层次遍历
    8. void LevOrder(Node* root)
    9. {
    10. queue qq;//定义队列qq,存储指向每个结点的指针
    11. if(root == NULL)
    12. {
    13. return;
    14. }
    15. Node* front = NULL;//定义指向队头的指针
    16. qq.push(root);//将根节点入队
    17. while(!qq.empty())
    18. {
    19. front = qq.front();//先获取队头,才能在出队后访问其左右孩子
    20. qq.pop();//队头出队
    21. printf("%c", front->value);//输出队头的value
    22. //将当前front的左右孩子入队
    23. if (front->left != NULL)
    24. qq.push(front->left);
    25. //不用输出左右孩子,因为pop出队头后,左右孩子会成为新对头,每次只用输出队头元素
    26. if(front->right != NULL)
    27. qq.push(front->right);
    28. }
    29. printf("%\n");
    30. }

    完整代码:

     

    1. typedef struct node
    2. {
    3. char value;//当前节点值
    4. struct node* left;//指向当前节点左孩子指针
    5. struct node* right;//指向当前节点右孩子指针
    6. }Node;
    7. typedef struct tree
    8. {
    9. Node* root;
    10. }Tree;
    11. void InitTree(Tree* t)
    12. {
    13. t->root = NULL;
    14. }
    15. //先序遍历创建二叉树
    16. Node* Create(const char*& str) //因为要修改字符串就加了引用&
    17. {
    18. if (*str == '*')
    19. return NULL;
    20. else
    21. {
    22. Node* newnode = (Node*)malloc(sizeof(Node));
    23. if (newnode != NULL)
    24. {
    25. newnode->value = *str;
    26. newnode->left = Create(++str);
    27. newnode->right = Create(++str);
    28. return newnode;
    29. }
    30. }
    31. }
    32. //层次遍历
    33. void LevOrder(Node* root)
    34. {
    35. queue qq;//定义队列qq,存储指向每个结点的指针
    36. if(root == NULL)
    37. {
    38. return;
    39. }
    40. Node* front = NULL;//定义指向队头的指针
    41. qq.push(root);//将根节点入队
    42. while(!qq.empty())
    43. {
    44. front = qq.front();//先获取队头,才能在出队后访问其左右孩子
    45. qq.pop();//队头出队
    46. printf("%c", front->value);//输出队头的value
    47. //将当前front的左右孩子入队
    48. if (front->left != NULL)
    49. qq.push(front->left);
    50. //不用输出左右孩子,因为pop出队头后,左右孩子会成为新对头,每次只用输出队头元素
    51. if(front->right != NULL)
    52. qq.push(front->right);
    53. }
    54. printf("\n");
    55. }
    56. int main()
    57. {
    58. Tree t;
    59. InitTree(&t);
    60. const char* str = "ABDG**HI****CE*J**F**";
    61. t.root = Create(str);
    62. printf("层次遍历二叉树:\n");
    63. LevOrder(t.root);
    64. printf("\n");
    65. }

        说明:上图代码的创建二叉树的思想:创建二叉树 

    运行结果:

     

  • 相关阅读:
    TCP/IP(十二)TCP的确认、超时、重传机制
    Go中间件
    一文讲完Java常用设计模式(23种)
    正方形(c++题解)
    OpenCV每日函数 计算摄影模块(1) 图像修复算法 inpaint函数
    基于Arduino的物流分拣控制系统设计
    15天获取20万用户,小程序如何做到?
    【Qt】Qt中的中心部件意义
    解决shell报错syntax error near unexpected token `fi‘
    高效数据通道支撑生产情况实时分析与可视化
  • 原文地址:https://blog.csdn.net/qq_53830608/article/details/126212892