【数据结构】二叉树的前中后序遍历(C语言)

简介: 【数据结构】二叉树的前中后序遍历(C语言)

什么是二叉树

[二叉树] 顾名思义就是有两个分支节点的树,不仅如此,除了叶子外的所有节点都具有两个分支节点;

由于结构像一棵倒立的树,顾名思义为二叉树

如下图所示,该图即为一棵野生的二叉树

既然二叉树为树,固然有着和树一样的部分(叶子、根、分支…)

这些也成为了树相关的概念;


树相关的概念

  • 叶子节点或者终端节点

叶子节点或终端节点,顾名思义就是最底端的节点,该节点不存在分支,故被称为叶子;


  • 节点的度

节点的度即为一个节点含有的子树成为该节点的度,如图所示,节点C的度为3;


  • 双亲结点(父节点)

若是一个节点存在子节点则该节点成为该子节点的父节点;如上图所示,A节点既是B的父节点,也是C的父节点;


  • 兄弟节点

具有相同父节点的节点成称为兄弟节点,“双亲结点”中所提到的“A结点既是B的父节点,也是C的父结点”处中的BC节点即为兄弟节点。


  • 树的度

树的度即为一棵树中,最大的节点的度,如“结点的度”中的C节点,该节点为整棵树中度最大的结点为3,故该树的度为3;


  • 树的高度或深度

树中结点的最大层次即为树的高度,如上图所示,树的高度为3;


  • 堂兄弟节点

双亲在同一层的节点互为堂兄弟,如上图所示,E节点和F节点护卫堂兄弟节点;


  • 节点的祖先

从根到节点所经分支上的所有节点,如上图所示,A节点为所有节点的祖先;


  • 子孙

以某节点为根的子树中任意一个节点都称为该节点的子孙

如上图所示,除A以外的所有其他节点都为A节点的子孙;


  • 森林

由m(m>0)棵互不相交的树的集合称为森林;


树的表示形式

树的结构与线性表相比就会更加复杂,既要保存值域,同时也要保存树中节点与节点之间的关系;在树中有许多的表示方法(双亲表示法、孩子表示法、孩子双亲表示法、孩子兄弟表示法等等),在此就不做过多赘述;

既然树的结构如此复杂,那对于真正实际中,树有什么应用呢?大家可以将计算机中的文件夹进行比较,从一个文件夹可以分支出很多个文件夹,文件夹内还可以继续存放文件夹,如此;

在Linux操作系统就应用了文件目录树,目录树的起点是根目录,Linux文件系统中的每一文件在此目录树中的文件名都是独一无二的,因为其包含从根目录开始的完整路径;

同时在很多算法中,都运用到了树;


特殊的二叉树

二叉树在树中也算是一个比较特殊的树种,但在二叉树中也存在着特殊的二叉树,即为完全二叉树与满二叉树

  • 满二叉树
    一个二叉树,如果每一层的节点树都达到最大值,则这个二叉树就是满二叉树;也就是说,如果一个二叉树的层数为k,且节点总数是2^k-1,则它就是满二叉树;
  • 完全二叉树
    完全二叉树是一种效率很高的树,是由满二叉树引申出来的。对于深度为k的,有n个节点的二叉树,当且仅当其每个节点都与深度k的满二叉树中编号从1至n的节点一一对应时称为完全二叉树,同时满二叉树也是一种特殊的完全二叉树。

如何创造出一棵二叉树

在不使用任何算法的前提下若是想得到一棵二叉树可以使用比较简单粗暴的方式:

将各个节点创建并将每个节点连接在一起(该方法适用于任何一种树);

根据树的结构我们可以得知,树既要保存值域,同时也要保存节点之间的关系,又因为为二叉树(每个节点必有两个分支)

假设需要创建一个如图所示的二叉树

在此处可以定义一个结构体,并在结构体内存放结构体指针用来存放左右两个子树,同时创建一个成员变量用来存放所需要存储的值域

typedef char BTDataType;
typedef struct BinaryNode
{
  struct BinaryNode*left;
  struct BinaryNode*right;
  BTDataType a;
}BTNode;

根据图所示可知,A节点的子节点为B、C;

B节点的子节点为D、E;

C节点的子节点为F、G;

int main()
  {
    BTNode q1;
    BTNode q2;
    BTNode q3;
    BTNode q4;
    BTNode q5;
    BTNode q6;
    BTNode q7;
    q1.a = 'A';
    q2.a = 'B';
    q3.a = 'C';
    q4.a = 'D';
    q5.a = 'E';
    q6.a = 'F';
    q7.a = 'G';
    q1.left = &q2;
    q1.right = &q3;
    q2.left = &q4;
    q2.right = &q5;
    q3.left = &q6;
    q3.right = &q7;
    q4.left = q4.right = q5.left = q5.right =q6.left = q6.right = q7.left = q7.right =NULL;
    return 0;
  }

二叉树的遍历

二叉树的遍历分为先序遍历,中序遍历,后序遍历以及层序遍历

为什么会叫先中后,顾名思义,这里的先中后为遍历过程中根节点的访问顺序,一棵树的任意子树都可以看成根节点和子树;

至于层序遍历,即为一层一层的进行访问;

首先设存在一棵二叉树

先序遍历(前序遍历)

先序遍历的遍历方式为:根、左子树、右子树

按照该树可以得出,该树的前序遍历为:A,B,D,E,C,F,G

根据根、左子树、右子树的顺序可知,最先访问的必定是A节点,当A节点访问完即访问左子树,而左子树的根节点为B,B访问结束访问B的左子树,为D,D没有左右子树(为空)故返回访问B的右子树,E与D同理,而后B访问结束放回根节点A并访问A的右树,同理得出该树的前序遍历为 A,B,D,E,C,F,G

既然看图可以得出树的前序遍历,那在代码中如何表示出二叉树的前序遍历,该处只需要使用递归的方式,按照根、左、右的方式即可;

void BinaryTreePreOrder(BTNode*root)
{
  if(root==NULL){//当root为空时则表示该处无节点,即无存储有效数据,若是访问则会造成对空指针的非法解引用
    printf("NULL");
    return ;
  }
  printf("%c ",root->a);//若是不为空则打印出该节点内所存储的有效数据
  BinaryTreePreOrder(root->left);//访问该节点的左子树
  BinaryTreePreOrder(root->right);//访问该节点的右子树
}

如图所示


中序遍历

中序遍历的遍历顺序为:左子树、根、右子树

按照该树可得出中序遍历的结果为:D,B,E,A,F,C,G;

若是用代码方式表示即为:

void BinaryTreeInOrder(BTNode*root)
{
  if(root==NULL){//当root为空时则表示该处无节点,即无存储有效数据,若是访问则会造成对空指针的非法解引用
    printf("NULL");
    return;
  }
  printf("%c ",root->a);//若是不为空则打印出该节点内所存储的有效数据
  BinaryTreeInOrder(root->left);//访问该节点的左子树
  BinaryTreeInOrder(root->right);//访问该节点的右子树
}

后序遍历

中序遍历的遍历顺序为:左子树、右子树、根

按照该树可得出中序遍历的结果为:D,E,B,F,G,C,A;

若是用代码方式表示即为:

void BinaryTreePostOrder(BTNode*root)
{
  if(root==NULL){//当root为空时则表示该处无节点,即无存储有效数据,若是访问则会造成对空指针的非法解引用
    printf("NULL");
    return;
  }
  BinaryTreePostOrder(root->left);//访问该节点的左子树
  BinaryTreePostOrder(root->right);//访问该节点的右子树
  printf("%c ",root->a);//若是不为空则打印出该节点内所存储的有效数据
}

总结

二叉树除了前中后序遍历以外还有一种遍历方式叫作层序遍历,可以使用队列的FIFO特性从而完成该遍历的实现;

在利用递归实现解决二叉树相关问题的过程中,可以根据实际情况选择相应的遍历方式从而以效率较高的方式解决问题;

所有的二叉树问题都可以将其分为两个子问题进行解决;

相关文章
|
4天前
|
定位技术 C语言
c语言及数据结构实现简单贪吃蛇小游戏
c语言及数据结构实现简单贪吃蛇小游戏
|
22天前
|
搜索推荐 C语言
数据结构(C语言)之对归并排序的介绍与理解
归并排序是一种基于分治策略的排序算法,通过递归将数组不断分割为子数组,直到每个子数组仅剩一个元素,再逐步合并这些有序的子数组以得到最终的有序数组。递归版本中,每次分割区间为[left, mid]和[mid+1, right],确保每两个区间内数据有序后进行合并。非递归版本则通过逐步增加gap值(初始为1),先对单个元素排序,再逐步扩大到更大的区间进行合并,直至整个数组有序。归并排序的时间复杂度为O(n*logn),空间复杂度为O(n),且具有稳定性,适用于普通排序及大文件排序场景。
|
1月前
|
C++
【C++数据结构——树】二叉树的性质(头歌实践教学平台习题)【合集】
本文档介绍了如何根据二叉树的括号表示串创建二叉树,并计算其结点个数、叶子结点个数、某结点的层次和二叉树的宽度。主要内容包括: 1. **定义二叉树节点结构体**:定义了包含节点值、左子节点指针和右子节点指针的结构体。 2. **实现构建二叉树的函数**:通过解析括号表示串,递归地构建二叉树的各个节点及其子树。 3. **使用示例**:展示了如何调用 `buildTree` 函数构建二叉树并进行简单验证。 4. **计算二叉树属性**: - 计算二叉树节点个数。 - 计算二叉树叶子节点个数。 - 计算某节点的层次。 - 计算二叉树的宽度。 最后,提供了测试说明及通关代
46 10
|
1月前
|
Java C++
【C++数据结构——树】二叉树的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现二叉树的基本运算。​ 相关知识 创建二叉树 销毁二叉树 查找结点 求二叉树的高度 输出二叉树 //二叉树节点结构体定义 structTreeNode{ intval; TreeNode*left; TreeNode*right; TreeNode(intx):val(x),left(NULL),right(NULL){} }; 创建二叉树 //创建二叉树函数(简单示例,手动构建) TreeNode*create
48 12
|
1月前
|
数据采集 存储 算法
【C++数据结构——图】图的遍历(头歌教学实验平台习题) 【合集】
本文介绍了图的遍历算法,包括深度优先遍历(DFS)和广度优先遍历(BFS)。深度优先遍历通过递归方式从起始节点深入探索图,适用于寻找路径、拓扑排序等场景;广度优先遍历则按层次逐层访问节点,适合无权图最短路径和网络爬虫等应用。文中提供了C++代码示例,演示了如何实现这两种遍历方法,并附有测试用例及结果,帮助读者理解和实践图的遍历算法。
44 0
|
1月前
|
存储 算法 测试技术
【C++数据结构——树】二叉树的遍历算法(头歌教学实验平台习题) 【合集】
本任务旨在实现二叉树的遍历,包括先序、中序、后序和层次遍历。首先介绍了二叉树的基本概念与结构定义,并通过C++代码示例展示了如何定义二叉树节点及构建二叉树。接着详细讲解了四种遍历方法的递归实现逻辑,以及层次遍历中队列的应用。最后提供了测试用例和预期输出,确保代码正确性。通过这些内容,帮助读者理解并掌握二叉树遍历的核心思想与实现技巧。
51 2
|
2月前
|
数据库
数据结构中二叉树,哈希表,顺序表,链表的比较补充
二叉搜索树,哈希表,顺序表,链表的特点的比较
数据结构中二叉树,哈希表,顺序表,链表的比较补充
|
3月前
|
算法 数据处理 C语言
C语言中的位运算技巧,涵盖基本概念、应用场景、实用技巧及示例代码,并讨论了位运算的性能优势及其与其他数据结构和算法的结合
本文深入解析了C语言中的位运算技巧,涵盖基本概念、应用场景、实用技巧及示例代码,并讨论了位运算的性能优势及其与其他数据结构和算法的结合,旨在帮助读者掌握这一高效的数据处理方法。
91 1
|
3月前
|
并行计算 算法 测试技术
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面,旨在通过综合策略提升程序性能,满足实际需求。
99 1
|
3月前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
99 5

热门文章

最新文章