数据结构-二叉树的定义、创建和周游(前序、中序、后序和层序)

  • 前言
  • 二叉树
    • 二叉树的定义
    • 完全二叉树的创建
  • 二叉树的周游
    • 前序遍历
      • 递归解决
      • 迭代解决
    • 中序遍历
      • 递归解决
      • 迭代解决
    • 后序迭代
      • 递归解决
      • 迭代解决
    • 层序遍历

前言

课程学习用书为《算法与数据结构-C语言描述(第三版)》
此次使用语言为C++,为了使程序清晰,建立了多个.h和.cpp的类进行实现
完整代码上传至Github可自行下载:

https://github.com/Junzhou-Chen/Binary-tree

其中包括队列与二叉树的定义、创建和周游,使用时引用头文件即可

二叉树

树 是一种经常用到的数据结构,用来模拟具有树状结构性质的数据集合。

树里的每一个节点有一个值和一个包含所有子节点的列表。从图的观点来看,树也可视为一个拥有N 个节点和N-1 条边的一个有向无环图。

二叉树是一种更为典型的树状结构。如它名字所描述的那样,二叉树是每个节点最多有两个子树的树结构,通常子树被称作“左子树”和“右子树”。

二叉树的定义

二叉树包括树值、左子树节点、右子树节点,具体节点定义如下

 struct TreeNode {int val;TreeNode *left;TreeNode *right;TreeNode() : val(0), left(nullptr), right(nullptr) {}TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}  };

完全二叉树的创建

一棵深度为k的有n个结点的二叉树,对树中的结点按从上至下、从左到右的顺序进行编号,如果编号为i(1≤i≤n)的结点与满二叉树中编号为i的结点在二叉树中的位置相同,则这棵二叉树称为完全二叉树。
这里对函数提供数组,通过层序遍历方式建立二叉树,主要运用数据结构中队列的概念。

TreeNode* SolutionTree::SetTree(std::vector<int> nums) // 建立完全二叉树
{if (nums.empty())return NULL;TreeNode* root = new TreeNode(nums[0]);queue<TreeNode*> saveNode;saveNode.push(root);for (int i = 1; i < nums.size();i++) {int num = nums[i];auto Node = saveNode.front();if (!Node->left) {TreeNode* left = new TreeNode(num);Node->left = left;saveNode.push(left);}else {TreeNode* right = new TreeNode(num);Node->right = right;saveNode.pop();saveNode.push(right);}}return root;
}

二叉树的周游

二叉树周游实现仔细阅读代码即可理解,就不详细介绍了,如有问题可私信。

前序遍历

按照访问根节点——左子树——右子树的方式遍历这棵树,而在访问左子树或者右子树的时候,我们按照同样的方式遍历,直到遍历完整棵树。

递归解决

void preorder(TreeNode* root, vector<int>& res) {if (root == nullptr) {return;}res.push_back(root->val);preorder(root->left, res);preorder(root->right, res);
}vector<int> SolutionTree::RecPreorderTraversal(TreeNode* root)// 前序递归
{vector<int> nums;preorder(root, nums);return nums;
}

迭代解决

std::vector<int> SolutionTree::ItePreorderTraversal(TreeNode* root) // 前序迭代
{vector<int> nums;if (root == nullptr) {return nums;}stack<TreeNode*> stk;TreeNode* node = root;while (!stk.empty() || node != nullptr) {while (node != nullptr) {nums.push_back(node->val);stk.push(node);node = node->left;}node = stk.top();stk.pop();node = node->right;}return nums;
}

中序遍历

按照访问左子树——根节点——右子树的方式遍历这棵树,而在访问左子树或者右子树的时候我们按照同样的方式遍历,直到遍历完整棵树。

递归解决

void inorder(TreeNode* root, vector<int>& res) {if (!root) {return;}inorder(root->left, res);res.push_back(root->val);inorder(root->right, res);
}std::vector<int> SolutionTree::RecInorderTraversal(TreeNode* root)// 中序递归
{vector<int> res;inorder(root, res);return res;
}

迭代解决

std::vector<int> SolutionTree::IteInorderTraversal(TreeNode* root)// 中序迭代
{vector<int> nums;stack<TreeNode*> stk;while (root != nullptr || !stk.empty()) {while (root != nullptr) {stk.push(root);root = root->left;}root = stk.top();stk.pop();nums.push_back(root->val);root = root->right;}return nums;
}

后序迭代

按照访问左子树——右子树——根节点的方式遍历这棵树,而在访问左子树或者右子树的时候,我们按照同样的方式遍历,直到遍历完整棵树。

递归解决

void postorder(TreeNode* root, vector<int>& nums) {if (root == nullptr) {return;}postorder(root->left, nums);postorder(root->right, nums);nums.push_back(root->val);
}std::vector<int> SolutionTree::RecPostorderTraversal(TreeNode* root)// 后序递归
{vector<int> nums;postorder(root, nums);return nums;
}

迭代解决

std::vector<int> SolutionTree::ItePostorderTraversal(TreeNode* root)// 后序迭代
{vector<int> nums;if (root == nullptr) {return nums;}stack<TreeNode*> stk;TreeNode* prev = nullptr;while (root != nullptr || !stk.empty()) {while (root != nullptr) {stk.emplace(root);root = root->left;}root = stk.top();stk.pop();if (root->right == nullptr || root->right == prev) {nums.emplace_back(root->val);prev = root;root = nullptr;}else {stk.emplace(root);root = root->right;}}return nums;
}

层序遍历

逐层地,从左到右访问所有节点

std::vector<std::vector<int>> SolutionTree::LevelOrder(TreeNode* root)// 层序递归
{vector <vector <int>> ret;if (!root) {return ret;}queue <TreeNode*> q;q.push(root);while (!q.empty()) {int currentLevelSize = q.size();ret.push_back(vector <int>());for (int i = 1; i <= currentLevelSize; ++i) {auto node = q.front(); q.pop();ret.back().push_back(node->val);if (node->left) q.push(node->left);if (node->right) q.push(node->right);}}return ret;
}

数据结构-二叉树的定义、创建和周游(前序、中序、后序和层序)相关推荐

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

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

  2. 用前序中序创建二叉树(用中序后序创建二叉树)

    定义二叉树结点 比如就拿这个二叉树 前序中序创建 因为前序遍历的顺序是 根 , 左 ,右. 中序的遍历是 左 根 右. 我们会很不好想,但我们可以用前序和中序把上面那个二叉树的遍历一边 前序遍历:AB ...

  3. C++用类实现二叉树的创建,前序中序后序遍历(附完整代码)

    C++用类实现二叉树的创建,前序中序后序遍历(附完整代码) 前序.中序.后序遍历 直接上代码 前序.中序.后序遍历 二叉树的遍历分为前序遍历,中序遍历和后序遍历三种遍历方法.前序遍历的顺序为" ...

  4. 【二叉树Java】二叉树遍历前序中序后序遍历的非递归写法

    本文主要介绍二叉树前序中序后序遍历的非递归写法 在探讨如何写出二叉树的前序中序后序遍历代码之前,我们先来明确一个问题,前序中序后序遍历根据什么区分? 二叉树的前序中序后序遍历,是相较根节点说的.最先遍 ...

  5. 二叉树的前序中序后序遍历java代码实现

    1.前序遍历概述 前序遍历(VLR) 是二叉树遍历的一种,也叫做先根遍历.先序遍历.前序周游,可记做根左右.前序遍历首先访问根结点然后遍历左子树,最后遍历右子树. 若二叉树为空则结束返回,否则: (1 ...

  6. 二叉树的深度(前序 中序 后序 递归非递归搜素)、广度、搜索 C++

    a b c 使用 1 2 3 表示 /* 描述:二叉树的深度(前序 中序 后序 递归非递归搜素).广度.搜索 作者:jz 日期:20140819 */ #include<stdio.h> ...

  7. 前序中序、中序后序以及前序后序构造二叉树

    文章目录 前序中序 中序后序 前序后序 定义的树节点如下, class TreeNode {int val;TreeNode left;TreeNode right;TreeNode(int x) { ...

  8. 二叉树中前序 中序 后序的互推

    最近开始复习数据结构,就从二叉树开始吧 1.复习前序 中序 后序 结构: 前序:根(左子树)(右子树) 中序:(左子树)根 (右子树) 后序:(左子树)(右子树)根 2. 前序+中序->后序 由 ...

  9. 二叉树遍历(递归实现前序/中序/后序遍历)

    1. 准备工作 我们先定义一棵普通的二叉树,如下图 2. 前序遍历 通过递归进行遍历: 如果二叉树为空,则操作返回: 如果非空,否则从根结点开始,然后遍历左子树,再遍历右子树. 前序遍历的结果是:AB ...

  10. 二叉树的前序中序后序三种遍历方式及递归算法介绍

    二叉树三种遍历方式 二叉树的遍历是整个二叉树的核心,二叉树的几本操作都要依赖于遍历,对于二叉树的遍历,递归是最简单也最容易理解的,本文详细介绍了二叉树的三种遍历方法,并用递归来实现: 完整的可调试代码 ...

最新文章

  1. Permission is only granted to system app
  2. wifi网络结构(下)
  3. Linux学习之系统编程篇:创建线程函数
  4. 第8章 线性时间排序
  5. 最常出现的字符串 Most Common Word
  6. 图像处理常用八大算法
  7. python标准化输出到txt_3大利器推荐,帮你写出规范漂亮的python代码
  8. Java实现微信刷屏(2)
  9. 股指期货首次和二次开户条件
  10. 云原生2.0时代,保险企业为何要迎智而上?
  11. bne 1b 汇编含义
  12. vivo手机html有吗,vivo手机有哪些系列?区别是什么?
  13. 10大H5前端框架(转)
  14. Java练习之坦克大战!!!复制可以直接用!!!文章最后有飞机大战代码!!!
  15. uni-app新闻小程序
  16. 「自控原理」5.1 频率特性及其图示
  17. linux上执行sql乱码,linux sqlplus乱码怎么办
  18. vr虚拟现实技术的前景!对未来发展带来有利的趋势吗?
  19. 从粗放式到精益化编程
  20. linux操作系统培训_免费在线技术培训丨SLE201v15 SUSE Linux Enterprise Server 15 管理课程...

热门文章

  1. 2021-02-04-scrapy爬虫案例1:爬取博客园新闻版块详情页-基础入门篇
  2. [渝粤教育] 天津师范大学 教育心理学(唐卫海) 参考 资料
  3. vue valley_12个无剧透的Stardew Valley秘诀和技巧,助您入门
  4. android 车载蓝牙音乐介绍
  5. CapstoneCS5212|CapstoneCS5218|DP转VGA1080P方案设计| DP转HDMI4K 30Hz方案设计
  6. wtl单文档选项_WTL体系结构
  7. c++builder:Project Project1.exe raised exception class EAccessViolation with message 'Access violati
  8. BUUCTF~Misc~Test5
  9. SX1308原厂芯片
  10. spark infer parquet schema