本文主要实现C语言对二叉树的构造,可存储所有类型数据,实现数据域的遍历,本文主要介绍递归的遍历方法,含详细图文;以及树高、叶子节点的计算等。

1 二叉树构造

typedef struct Tree //二叉树
{void *data;         //数据域,void* 可保存任意数据类型的地址struct Tree *left;  //左子节点指针struct Tree *right; //右子节点指针
} Tree;

2 根据数据data创建树节点

Tree *createTreeNode(void *data) //根据数据域data创建节点
{Tree *node = (Tree *)malloc(sizeof(Tree)); //在堆区申请内存node->data = data;node->left = NULL;node->right = NULL;
}

3 前序遍历代码(详细分析部分见8.2图解)

typedef struct Student //后续以二叉树保存Student数据信息为例
{int age;char name[20];
} Student;void preOrderList(Tree *root) //前序遍历,先根节点,再左(子树),再右(子树)
{if (root == NULL)return;Student *stu = (Student *)root->data;printf("{id:%d,name:%s}\t", stu->age, stu->name);preOrderList(root->left);preOrderList(root->right);
}
//8.2有详细图解分析过程

4 中序遍历

void inOrderList(Tree *root)
{if (root == NULL)return;inOrderList(root->left);Student *stu = (Student *)root->data;printf("{id:%d,name:%s}\t", stu->age, stu->name);inOrderList(root->right);
}

5 后序遍历

void postOrderList(Tree *root)
{if (root == NULL)return;postOrderList(root->left);postOrderList(root->right);Student *stu = (Student *)root->data;printf("{id:%d,name:%s}\t", stu->age, stu->name);
}

6 叶子节点数量计算

void countOfLeafNode(Tree *root, int *count) //统计二叉树的叶子节点,即没有左右子结点
{if (root == NULL)return;if (root->left == NULL && root->right == NULL)//叶子节点即没有后驱节点(*count)++;countOfLeafNode(root->left, count);//结合前序遍历计算叶子节点数量countOfLeafNode(root->right, count);
}

7 树高计算

size_t heightOfTree(Tree *root)//函数的分析过程,可结果8.2图解对前序遍历的分析
{if (root == NULL)return 0;int heightOfLeftTree = heightOfTree(root->left);int heightOfRightTree = heightOfTree(root->right);int heightOfTree = heightOfLeftTree > heightOfRightTree ? heightOfLeftTree + 1 : heightOfRightTree + 1;//得到左子树和右子树的高度最大值,再加一,即树高return heightOfTree;
}

8 函数测试与结果分析

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{Student stu[7] = {{1, "jakes1"},{2, "jakes2"},{3, "jakes3"},{4, "jakes4"},{5, "jakes5"},{6, "jakes6"},{7, "jakes7"},};Tree *root = (Tree *)malloc(sizeof(Tree));root->data = &stu[0];root->left = createTreeNode(&stu[1]);root->right = createTreeNode(&stu[2]);root->left->left = createTreeNode(&stu[3]);root->left->left->right = createTreeNode(&stu[6]);root->right->left = createTreeNode(&stu[4]);root->right->right = createTreeNode(&stu[5]);printf("前序遍历:");preOrderList(root);printf("\n中序遍历:");inOrderList(root);printf("\n后序遍历:");postOrderList(root);puts("");int count = 0;countOfLeafNode(root, &count);//count入参传址printf("叶子节点数量为:%d\n", count);printf("树的高度为%d\n", heightOfTree(root));return 0;
}

8.1 main函数中,对树的构建如下图

8.2 以前序遍历为例,程序的执行顺序可参考下图。preOrderList()函数入参为Tree *类型,为简单绘图,简化为stu0、stu1.....,图中有4个printf(NULL),应该是pre(NULL),图画得略微仓促,但有助于对递归排序的理解。

8.3 中序遍历和后续遍历均可按照此方法分析,main函数的运行结果如下:

9 补充一些关于树的基本概念
   9.1 根:没有前驱
   9.2 叶子:没有后继
   9.3 双亲:直接前驱
   9.4 孩子:直接后继
   9.5 节点的度:直接后继的数量
   9.6 树的度:节点的度中取最大值
   9.7 树的高度/深度:最大层数
   9.8 二叉树:
        9.8.1 在二叉树的第i层上最多2^(i-1)个节点
        9.8.2 深度为k的二叉树至多有2^k-1个节点,若有2^k-1个节点,则成为满二叉树
                 若仅在最后一层缺少右边的若干节点,其他层节点数已达到最大,成为完全二叉树,
                 满二叉树肯定是完全二叉树
        9.8.3 若度为2的节点数有n个,则叶子数必定为n+1;(叶子是指没有后继)
        9.8.4 具有n个节点的完全二叉树的深度必为int((log2)n)+1
        9.8.5对于完全二叉树,若从左至右,从上到下,对节点编号,节点i的左子节点必为2i

右子节点必为2i+1,父节点必为(int)i/2

点击关注不迷路

C语言实现 二叉树 对任意类型数据的遍历、叶子节点统计、树高计算相关推荐

  1. C语言实现 动态数组 处理任意类型数据

    引言:动态数组在C/C++.Java.Python等语言中应用广泛,高级语言一般通过调用类或接口等可以快捷使用,C语言实现动态数组需要手动构造,以下为实现过程. 1 结构体构造动态数组 typedef ...

  2. 数据结构与算法:单链表(利用万能指针实现对任意类型数据进行操作)

    前言 C语言的指针真的很强大,万能指针更强大,可以指向任意类型的数据.在上篇博客 数据结构与算法:单链表(超详细实现)中用C语言实现了单链表的相关算法,不过却有局限性 只能针对某一种数据类型还是不够强 ...

  3. JS 递归树结构数据查找所有叶子节点

    JS 递归树结构数据查找所有叶子节点 export function getAllLeaf (data) {let result = []function getLeaf (data) {data.f ...

  4. 数据结构与算法实验 实验6:二叉树ADT的二叉链式实现 (由完全前序序列创建二叉树 / 求二叉树的节点数/树高/叶子节点数 /先序中序后序层序遍历)

    假设二叉数的数据元素为字符,采用二叉链式存储结构.请编码实现二叉树ADT,其中包括创建二叉树.遍历二叉树(深度.广度).求二叉树的深度(高度).计算二叉树的元素个数.计算二叉树的叶子数.二叉树的格式输 ...

  5. 二叉树叶子结点,非叶子节点以及深度的计算

    二叉树叶子结点的计算 //统计叶子结点的数目 int LeafNum(BiTree T) {if (!T) {return 0;} else if (!T->lchild && ...

  6. Emscripten返回任意类型数据

    使用 emscripten::val 可以在c++函数中可以返回int.string.bool等多种类型. #include <emscripten/val.h> #include < ...

  7. 255字符c语言中,在单片机C语言程序设计中,______类型数据经常用于处理ASCⅡ字符或处理小于等于255的整型数 答案:char...

    夫通性转导,各说过者也:噬菌体转导供体菌染色体时位之义 随机抽样又名()耳:概率抽样 六十岁男,病患高血压年,忽见心慌.闷.膺而迫性疼痛,诊为暴心痛,应用何药宜也:硝酸甘油舌下含化 如寄生义类计算机疢 ...

  8. dataframe类型数据的遍历_Python零基础入门到爬虫再到数据分析,这些你都是要学会的...

    1.必须知道的两组Python基础术语 A.变量和赋值 Python可以直接定义变量名字并进行赋值的,例如我们写出a = 4时,Python解释器干了两件事情: 在内存中创建了一个值为4的整型数据 在 ...

  9. 【C语言】二叉树前序中序后序遍历详解!!!内附算法好题初阶(每日小细节021)

    二叉树三种遍历方式时刻牢记,所谓的前中后就是根的位置 前序:根->左子树->右子树 中序:左子树->根->右子树 后序:左子树->右子树->根 每日小细节新增算法好 ...

最新文章

  1. 11. Django 引入富文本编辑器KindEditor
  2. 4.3.3 IPv4地址
  3. Linux下网络编程
  4. junit进行测试加载多个spring配置文件
  5. 时频分析:短时傅里叶变换应用
  6. oracle语句转成mysql语句_如何监控Mysql语句
  7. java swing运行没反应_java – 无法从命令行运行swing
  8. 为什么说选择正确的编程语言很重要,以及如何正确的选择
  9. 简单的签到代码_PHP实现一个小小的签到功能,到底用MySQL还是Redis?
  10. 2018 CVPR GAN 相关论文
  11. 1.7 LINUX启动流程
  12. 解决 GitHub 拉取代码网速慢的问题
  13. 6.5移相器(Phasers)
  14. 微信小程序UI库组件库合集
  15. 安川ga700变频器故障码集_安川变频器故障代码
  16. apiCloud实现微信分享功能
  17. 读书笔记-MySql必知必会(二)
  18. 在法国读计算机研究生的日子开始了
  19. Clickhouse 函数基础入门
  20. 干支纪年法简便算法_2020年天干地支对照表,干支日历表

热门文章

  1. 伽利略红十字来信谭之一:哈勃红歌红限红移谭
  2. 《新神榜:杨戬》这样的爆款影视动漫作品,原来都掌握了一个成功密码
  3. 华为认证网络工程师含金量高吗
  4. oracle bulk select,批量查询 Oracle的bulk collect用法
  5. varnish2.04配置
  6. 没有权限cd linux,为什么linux在root权限下 打cd命令没有用,都显示没有那个目录或文件...
  7. 圆形头像、图片显示效果
  8. 快速了解Swagger及其快速入门
  9. 排序的几种方法(合并,快速,冒泡排序)
  10. 用selenium爬取csdn博客文章,并用4种方法提取数据