当前位置:   article > 正文

c++ 结构体遍历_二叉树(Binary Tree)的建立与遍历——C语言实现

结构体 遍历字段c++

867ed230b1fa9fe661f2a0396d03d7c6.png

一、运行环境简介

编辑器:VSCode + MicroSoft原生插件;

:cat:‍:dragon:运行环境: MinGW ;

:cat:‍:bust_in_silhouette:常用指令: gcc mian.c -o mian.exe

二、二叉树的定义

这里我们直接采用浙大数据结构课程中的代码。因为这种写法清晰明了,且便于后续扩展。

  1. typedef char ElementType;
  2. typedef struct TNode *Position; /* 结构体指针 */
  3. typedef Position BinTree; /* 二叉树类型 */
  4. struct TNode{ /* 树结点定义 */
  5. ElementType Data; /* 结点数据 */
  6. BinTree Left; /* 指向左子树 */
  7. BinTree Right; /* 指向右子树 */
  8. }TNode;
  9. 复制代码

三、如何创建一个二叉树?

先看代码再分析

  1. void CreateBinaryTree ( BinTree *T ) {
  2. ElementType ch;
  3. scanf("%c",&ch);
  4. if (ch == '#')
  5. *T = NULL;
  6. else {
  7. *T = (BinTree)malloc(sizeof(TNode));
  8. (*T)->Data = ch;
  9. CreateBinaryTree(&((*T)->Left));
  10. CreateBinaryTree(&((*T)->Right));
  11. }
  12. }
  13. 复制代码

1.解决此函数的形参疑问

我们知道,二叉树的类型被我们定义为 BinTree ,而它的原类型是指向二叉树结点 TNode 的指针。我一开始犯的错误是,我认为直接传入这里的指针 BinTree 给函数 CreateBinaryTree() 就可以得到创建的二叉树。事实上这里需要传入指针的指针,即这个结构体指针的地址 *BinTree 。 也就是说,我们事实上传入的是 ** TNode ,即结点指针的指针。而采用上面的定义,就相当于是一个降维的过程,我们可以少写一个*。

为什么要传入结点指针的指针呢?我的理解是,我们所使用的数据结构二叉树在基本操作中就依赖于指针,这相当于我们一开始就在操控指针(比如不修改二叉树的一些操作——先序中序后序遍历中,我们用到了指针),但这些指针是包含在二叉树这个类型中的,打个比方,就相当于一个没有取得其地址的普通类型。所以我们需要修改二叉树的时候,我们要考虑取所谓“普通类型”的地址,即我们要取指针的地址,因此我们会在 CreateBinaryTree() 中传入结点指针的指针,即 ** TNode ,又即 *Bintree

2.对代码的一些说明

这里建立的二叉树,实际上是扩展二叉树,这里采用先序遍历的顺序依次输入结点的值( char 类型),用 '#' 代表空结点。

例如:创建二叉树:第一层为A,第二层为B、C,第三层为D、F,D为B的左孩子,F为C的右孩子;我们需要输入 ABD###C#F##

四、二叉树的遍历——递归实现

3种递归实现仅仅是输出语句顺序不同。

其实现原理为

二叉树的先中后序遍历中经过的结点路径是一样的,但是访问各结点的时机不同,每个结点都会被经过三次,第一次经过就printf是先序,同理第二次printf是中序,第三次是后序。

1.先序遍历

  1. void PreOrderTraversal ( BinTree BT ) {
  2. if ( BT ) {
  3. printf("%c", BT->Data);
  4. PreOrderTraversal( BT->Left );
  5. PreOrderTraversal( BT->Right );
  6. }
  7. }
  8. 复制代码

2.中序遍历

  1. void InOrderTraversal ( BinTree BT ) {
  2. if ( BT ) {
  3. PreOrderTraversal( BT->Left );
  4. printf("%c", BT->Data);
  5. PreOrderTraversal( BT->Right );
  6. }
  7. }
  8. 复制代码

3.后序遍历

  1. void PostOrderTraversal ( BinTree BT ) {
  2. if ( BT ) {
  3. PostOrderTraversal( BT->Left );
  4. PostOrderTraversal( BT->Right );
  5. printf("%c", BT->Data);
  6. }
  7. }
  8. 复制代码

五、其他操作

1.先序遍历输出二叉树叶子结点

  1. void PreOrderPrintLeaves ( BinTree BT ) {
  2. if ( BT ) {
  3. if ( !BT->Left && !BT->Right )
  4. printf("%c", BT->Data);
  5. PreOrderPrintLeaves( BT->Left );
  6. PreOrderPrintLeaves( BT->Right );
  7. }
  8. }
  9. 复制代码

2.后序遍历求二叉树的高度

  1. int PostOrderGetHeight ( BinTree BT) {
  2. int HL, HR, MaxH;
  3. if ( BT ) {
  4. HL = PostOrderGetHeight( BT->Left );
  5. HR = PostOrderGetHeight( BT->Right );
  6. MaxH = ( HL > HR ) ? HL : HR;
  7. return (MaxH + 1);
  8. }
  9. else
  10. return 0;
  11. }
  12. 复制代码

六、测试

程序结构:

头文件为BTree.h,里面包含上述代码。主要程序文件为main.c,包含代码如下:

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include"BTree.h"
  4. int main() {
  5. BinTree myTree;
  6. printf("Create your Binary Tree:n");
  7. CreateBinaryTree(&myTree);
  8. printf("n PreOrder:");
  9. PreOrderTraversal(myTree);
  10. printf("n InOrder:");
  11. InOrderTraversal(myTree);
  12. printf("n PostOrder:");
  13. PostOrderTraversal(myTree);
  14. printf("n Leaves:");
  15. PreOrderPrintLeaves(myTree);
  16. printf("n");
  17. int high = PostOrderGetHeight(myTree);
  18. printf("The height of the tree: %4d", high);
  19. return 0;
  20. }
  21. 复制代码

测试结果如下:

84ac20fbde67cf8e36fcc55f34defb77.png

cdee09fa09bcab19603798d68c07d39d.png

cfe45e692ad60449ec2b5d334b84e153.png

ddc9adc0af8667039f2bd2ec62e7fde1.png

点击链接领取资料,先到先得:

点击链接:领取新手礼包,学习资料​jq.qq.com
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/557760
推荐阅读
相关标签
  

闽ICP备14008679号