【算法与数据结构】二叉树(前中后)序遍历1

简介: 【算法与数据结构】二叉树(前中后)序遍历

📝前言

一棵二叉树是结点的一个有限集合,该集合:

  1. 或者为空
  2. 由一个根节点加上两棵别称为左子树和右子树的二叉树组成

二叉树可以没有节点(空树)否则,它包含一个根节点,这个根节点最多可以有两个分支:左子树和右子树,左右子树也符合二叉树的定义,可以是空树,或者由根节点和其左右子树组成。

因此二叉树的定义采用的是递归的思想:一个二叉树要么为空,要么由根节点和其左右两个子二叉树组成。左右子树本身也符合二叉树的定义,可以递归定义下去。


本小节我们将学习二叉树的前中后序遍历!


🌠 创建简单二叉树

在学习二叉树的基本操作之前,需要先创建一棵二叉树,然后才能学习相关的基本操作。由于现在大家对二叉树结构的理解还不够深入,为了降低学习成本,这里手动快速创建一棵简单的二叉树,以便快速进入二叉树操作学习。等大家对二叉树结构有了一定了解之后,再深入研究二叉树的真正创建方式。

手插简单二叉树代码:

// 二叉树节点结构体定义
typedef struct BinTreeNode
{
  // 左子节点指针
  struct BinTreeNode* left;

  // 右子节点指针
  struct BinTreeNode* right;

  // 节点值
  int val;
}BTNode;

// 创建节点,分配内存并返回
BTNode* BuyBTNode(int val)
{
  BTNode* newnode = (BTNode*)malloc(sizeof(BTNode));

  // 空间分配失败
  if (newnode == NULL)
  {
    perror("malloc fail");
    return NULL;
  }

  // 初始化节点值
  newnode->val = val;

  // 初始化左右子节点为NULL
  newnode->left = NULL;
  newnode->right = NULL;

  return newnode;
}

// 创建示例树
BTNode* CreateTree()
{
  // 创建节点1-6
  BTNode* n1 = BuyBTNode(1);
  BTNode* n2 = BuyBTNode(2);
  BTNode* n3 = BuyBTNode(3);
  BTNode* n4 = BuyBTNode(4);
  BTNode* n5 = BuyBTNode(5);
  BTNode* n6 = BuyBTNode(6);

  // 构建树结构
  n1->left = n2;
  n1->right = n4;
  n2->left = n3;
  n4->left = n5;
  n4->right = n6;

  return n1; // 返回根节点
}

二叉树的图像:

注意:上述代码并不是创建二叉树的方式,真正创建二叉树方式后序详解重点讲解。

🌉二叉树的三种遍历

学习二叉树结构,最简单的方式就是遍历。所谓二叉树遍历(Traversal)是按照某种特定的规则,依次对二叉树中的节点进行相应的操作,并且每个节点只操作一次。访问结点所做的操作依赖于具体的应用问题。 遍历是二叉树上最重要的运算之一,也是二叉树上进行其它运算的基础。


🌠前序

您说得对,我来补充一下前序遍历的注释:

前序遍历(Preorder Traversal 亦称先序遍历)——访问根结点的操作发生在遍历其左右子树之前。

算法:

访问根节点 -> 前序遍历左子树 -> 前序遍历右子树

  • 即先访问根节点,然后遍历其左子树,再遍历其右子树。

注意:

递归基准条件是当根节点为NULL时返回。访问根节点要放在递归左右子树之前,这保证了根节点一定先于其子节点被访问。递归左子树和右子树的顺序不能调换,否则就不是前序遍历了。

代码:

vvoid PreOrder(BTNode* root)
{
  if (root == NULL)
  {
    printf("N ");
    return;
  }

  printf("%d ", root->val);
  PreOrder(root->left);
  PreOrder(root->right);
}
int main()
{
  BTNode* root = CreateTree();
  PreOrder(root);
  printf("\n");
}

前序递归图解:

运行:

🌉中序遍历

中序遍历(Inorder Traversal)——访问根结点的操作发生在遍历其左右子树之中(间)。中序遍历是在遍历一个结点的左子树后,然后访问这个结点,最后遍历它的右子树。

void InOrder(BTNode* root)
{
  if (root == NULL)
  {
    printf("N ");
    return;
  }

  InOrder(root->left);
  printf("%d ", root->val);
  InOrder(root->right);
}

【算法与数据结构】二叉树(前中后)序遍历2:https://developer.aliyun.com/article/1474433

相关文章
|
2天前
|
存储 算法 Java
Java中,树与图的算法涉及二叉树的前序、中序、后序遍历以及DFS和BFS搜索。
【6月更文挑战第21天】Java中,树与图的算法涉及二叉树的前序、中序、后序遍历以及DFS和BFS搜索。二叉树遍历通过访问根、左、右子节点实现。DFS采用递归遍历图的节点,而BFS利用队列按层次访问。以下是简化的代码片段:[Java代码略]
10 4
|
2天前
|
算法 Python
数据结构算法--4堆排序
堆排序过程概述:建立大根堆,将堆顶最大元素移出并替换为末尾元素,调整保持堆性质,重复此过程直至堆为空,实现排序。时间复杂度为O(nlogn)。Python中可用heapq模块进行堆操作。
|
2天前
|
算法 Java 机器人
Java数据结构与算法:并发数据结构ConcurrentHashMap
Java数据结构与算法:并发数据结构ConcurrentHashMap
|
2天前
|
机器学习/深度学习 算法 搜索推荐
数据结构算法--2 冒泡排序,选择排序,插入排序
**基础排序算法包括冒泡排序、选择排序和插入排序。冒泡排序通过相邻元素比较交换,逐步将最大值“冒”到末尾,平均时间复杂度为O(n^2)。选择排序每次找到剩余部分的最小值与未排序部分的第一个元素交换,同样具有O(n^2)的时间复杂度。插入排序则类似玩牌,将新元素插入到已排序部分的正确位置,也是O(n^2)复杂度。这些算法适用于小规模或部分有序的数据。**
|
2天前
|
机器学习/深度学习 算法 索引
数据结构算法--1 顺序查找二分查找
**顺序查找时间复杂度为O(n)**,适合无序列表,可以通过`enumerate`或直接遍历索引来实现。**二分查找时间复杂度为O(logn)**,适用于有序列表,利用Python中`left`、`right`指针和`mid`点不断缩小搜索范围。效率上二分查找更优。
|
2天前
|
算法 网络协议 Java
我的Java数据结构和算法
我的Java数据结构和算法
7 0
|
2天前
|
算法 搜索推荐
数据结构算法--6 希尔排序和计数排序
**希尔排序**是插入排序的改进版,通过分组插入来提高效率。它逐步减少元素间的间隔(增量序列),每次对每个间隔内的元素进行插入排序,最终增量为1时进行最后一次直接插入排序,实现整体接近有序到完全有序的过程。例如,对数组`5, 7, 4, 6, 3, 1, 2, 9, 8`,先以间隔`d=4`排序,然后`d=2`,最后`d=1`,完成排序。计数排序则适用于0到100的数值,通过统计每个数出现次数,创建对应计数数组,再根据计数重建有序数组,时间复杂度为`O(n)`。
|
9天前
数据结构——栈和队列
数据结构——栈和队列
10 1
|
3天前
|
C++
【洛谷 P1044】[NOIP2003 普及组] 栈 题解(递归+记忆化搜索)
**NOIP2003普及组栈问题**:给定操作数序列1到n,仅允许push(进栈)和pop(出栈)操作。目标是计算所有可能的输出序列总数。输入包含一个整数n(1≤n≤18)。示例输入3,输出5。当队列空时返回1,栈空则只能入栈,栈非空时可入栈或出栈。AC C++代码利用记忆化搜索求解。
6 1
|
5天前
|
算法
$停车场管理系统 栈与队列
$停车场管理系统 栈与队列
5 1