数据结构-二叉树的定义、创建和周游(前序、中序、后序和层序)
数据结构-二叉树的定义、创建和周游(前序、中序、后序和层序)
- 前言
- 二叉树
- 二叉树的定义
- 完全二叉树的创建
- 二叉树的周游
- 前序遍历
- 递归解决
- 迭代解决
- 中序遍历
- 递归解决
- 迭代解决
- 后序迭代
- 递归解决
- 迭代解决
- 层序遍历
前言
课程学习用书为《算法与数据结构-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;
}
数据结构-二叉树的定义、创建和周游(前序、中序、后序和层序)相关推荐
- 数据结构与算法实验 实验6:二叉树ADT的二叉链式实现 (由完全前序序列创建二叉树 / 求二叉树的节点数/树高/叶子节点数 /先序中序后序层序遍历)
假设二叉数的数据元素为字符,采用二叉链式存储结构.请编码实现二叉树ADT,其中包括创建二叉树.遍历二叉树(深度.广度).求二叉树的深度(高度).计算二叉树的元素个数.计算二叉树的叶子数.二叉树的格式输 ...
- 用前序中序创建二叉树(用中序后序创建二叉树)
定义二叉树结点 比如就拿这个二叉树 前序中序创建 因为前序遍历的顺序是 根 , 左 ,右. 中序的遍历是 左 根 右. 我们会很不好想,但我们可以用前序和中序把上面那个二叉树的遍历一边 前序遍历:AB ...
- C++用类实现二叉树的创建,前序中序后序遍历(附完整代码)
C++用类实现二叉树的创建,前序中序后序遍历(附完整代码) 前序.中序.后序遍历 直接上代码 前序.中序.后序遍历 二叉树的遍历分为前序遍历,中序遍历和后序遍历三种遍历方法.前序遍历的顺序为" ...
- 【二叉树Java】二叉树遍历前序中序后序遍历的非递归写法
本文主要介绍二叉树前序中序后序遍历的非递归写法 在探讨如何写出二叉树的前序中序后序遍历代码之前,我们先来明确一个问题,前序中序后序遍历根据什么区分? 二叉树的前序中序后序遍历,是相较根节点说的.最先遍 ...
- 二叉树的前序中序后序遍历java代码实现
1.前序遍历概述 前序遍历(VLR) 是二叉树遍历的一种,也叫做先根遍历.先序遍历.前序周游,可记做根左右.前序遍历首先访问根结点然后遍历左子树,最后遍历右子树. 若二叉树为空则结束返回,否则: (1 ...
- 二叉树的深度(前序 中序 后序 递归非递归搜素)、广度、搜索 C++
a b c 使用 1 2 3 表示 /* 描述:二叉树的深度(前序 中序 后序 递归非递归搜素).广度.搜索 作者:jz 日期:20140819 */ #include<stdio.h> ...
- 前序中序、中序后序以及前序后序构造二叉树
文章目录 前序中序 中序后序 前序后序 定义的树节点如下, class TreeNode {int val;TreeNode left;TreeNode right;TreeNode(int x) { ...
- 二叉树中前序 中序 后序的互推
最近开始复习数据结构,就从二叉树开始吧 1.复习前序 中序 后序 结构: 前序:根(左子树)(右子树) 中序:(左子树)根 (右子树) 后序:(左子树)(右子树)根 2. 前序+中序->后序 由 ...
- 二叉树遍历(递归实现前序/中序/后序遍历)
1. 准备工作 我们先定义一棵普通的二叉树,如下图 2. 前序遍历 通过递归进行遍历: 如果二叉树为空,则操作返回: 如果非空,否则从根结点开始,然后遍历左子树,再遍历右子树. 前序遍历的结果是:AB ...
- 二叉树的前序中序后序三种遍历方式及递归算法介绍
二叉树三种遍历方式 二叉树的遍历是整个二叉树的核心,二叉树的几本操作都要依赖于遍历,对于二叉树的遍历,递归是最简单也最容易理解的,本文详细介绍了二叉树的三种遍历方法,并用递归来实现: 完整的可调试代码 ...
最新文章
- Permission is only granted to system app
- wifi网络结构(下)
- Linux学习之系统编程篇:创建线程函数
- 第8章 线性时间排序
- 最常出现的字符串 Most Common Word
- 图像处理常用八大算法
- python标准化输出到txt_3大利器推荐,帮你写出规范漂亮的python代码
- Java实现微信刷屏(2)
- 股指期货首次和二次开户条件
- 云原生2.0时代,保险企业为何要迎智而上?
- bne 1b 汇编含义
- vivo手机html有吗,vivo手机有哪些系列?区别是什么?
- 10大H5前端框架(转)
- Java练习之坦克大战!!!复制可以直接用!!!文章最后有飞机大战代码!!!
- uni-app新闻小程序
- 「自控原理」5.1 频率特性及其图示
- linux上执行sql乱码,linux sqlplus乱码怎么办
- vr虚拟现实技术的前景!对未来发展带来有利的趋势吗?
- 从粗放式到精益化编程
- linux操作系统培训_免费在线技术培训丨SLE201v15 SUSE Linux Enterprise Server 15 管理课程...
热门文章
- 2021-02-04-scrapy爬虫案例1:爬取博客园新闻版块详情页-基础入门篇
- [渝粤教育] 天津师范大学 教育心理学(唐卫海) 参考 资料
- vue valley_12个无剧透的Stardew Valley秘诀和技巧,助您入门
- android 车载蓝牙音乐介绍
- CapstoneCS5212|CapstoneCS5218|DP转VGA1080P方案设计| DP转HDMI4K 30Hz方案设计
- wtl单文档选项_WTL体系结构
- c++builder:Project Project1.exe raised exception class EAccessViolation with message 'Access violati
- BUUCTF~Misc~Test5
- SX1308原厂芯片
- spark infer parquet schema