数据结构与算法(c++)——查找二叉树与中序遍历
查找树ADT——查找二叉树
定义:对于树中的每个节点X,它的左子树中的所有项的值小于X中的项,而它的右子树中所有项的值大于X中的项。
现在给出字段和方法定义(BinarySearchTree.h)
#include <queue>
class BinarySearchTree {
private:
struct Node {
int value;
Node* left;
Node* right;
};
Node* root;
void insert(Node*, int);
void traversal(Node*, std::queue<int>&);
bool checkNode(Node*, int);
int findRoot(Node*, int, int);
public:
BinarySearchTree() : root(nullptr) {};
void insert(int);
std::queue<int> traversal();
int findRoot(int, int); // 查找两个节点的公共父节点
std::queue<int> morrisTraversal(); // (Morris方法)不使用递归和栈遍历二叉树
};
查找二叉树的遍历可以采用遍历和非遍历两种算法。
一、添加元素(insert)
现在假设要添加这样一组整数10,7,2,6,13,11,17,3。按照顺序形成的查找二叉树应该如下图:

算法实现:
void BinarySearchTree::insert(int val) {
Node* node = new Node();
node->value = val;
node->left = nullptr;
node->right = nullptr;
if (root == nullptr) {
root = node;
}
else {
insert(root, val);
}
}
void BinarySearchTree::insert(Node* node, int val) {
if (val < node->value) {
if (node->left != nullptr) {
insert(node->left, val);
}
else {
Node* chdNode = new Node();
chdNode->value = val;
chdNode->left = nullptr;
chdNode->right = nullptr;
node->left = chdNode;
}
}
else {
if (node->right != nullptr) {
insert(node->right, val);
}
else {
Node* chdNode = new Node();
chdNode->value = val;
chdNode->left = nullptr;
chdNode->right = nullptr;
node->right = chdNode;
}
}
}
二、遍历元素(递归)
查找二叉树的遍历需要采用中序法。即对于树中的每个节点来说首先处理左子树然后处理根节点再处理右子树。
算法实现:
std::queue<int> BinarySearchTree::traversal() {
std::queue<int> q;
if (root != nullptr) {
traversal(root, q);
}
return q;
}
void BinarySearchTree::traversal(Node* node, std::queue<int>& q) {
if (node->left != nullptr) {
traversal(node->left, q);
}
q.push(node->value);
if (node->right != nullptr) {
traversal(node->right, q);
}
}
三、查找树中任意两个节点的最小父节点
查找最小父节点的逻辑是对于给出的任意两个节点分别处于根节点的左侧与右侧。若两个节点均处于根节点左侧则向左子树递归遍历,反之,则向右子树递归遍历。如11和17,它们的最小父节点是13。一种例外情况是要求查找的两个节点其中一个是另一个的父节点。如2和3,它们的最小父节点是2。
算法实现:
int BinarySearchTree::findRoot(int a, int b) {
if (checkNode(root, a) && checkNode(root, b)) {
return findRoot(root, a, b);
}
}
int BinarySearchTree::findRoot(Node* node, int a, int b) {
if (a<node->value && b>node->value) {
return node->value;
}
else if (a < node->value && b < node->value) {
return findRoot(node->left, a, b);
}
else if (a > node->value && b > node->value) {
return findRoot(node->right, a, b);
}
else {
return a == node->value ? a : b;
}
}
四、遍历元素(不使用递归和栈)
分析:查找二叉树的遍历必须采用中序法,由于不能使用递归和栈。就需要使用特殊算法,能够在处理完X节点的右子树后向上检索到Y节点。如图:

Morris算法的特点就是在处理X节点前,首先找到其最右侧的子树b(b->right == nullptr)。然后建立与Y节点的连接(b->right = Y)。处理完成后再删除临时连接恢复二叉树的原装(b->right = nullptr)
算法实现:
std::queue<int> BinarySearchTree::morrisTraversal() {
std::queue<int> q;
if (root == nullptr) {
return q;
}
Node* cur = root;
Node* prev = nullptr;
while (cur != nullptr) {
if (cur->left == nullptr) {
q.push(cur->value);
cur = cur->right;
}
else {
prev = cur->left;
while (prev->right != nullptr && prev->right != cur) {
prev = prev->right;
}
if (prev->right == nullptr) {
prev->right = cur;
cur = cur->left;
}
else {
prev->right = nullptr;
q.push(cur->value);
cur = cur->right;
}
}
}
return q;
}
数据结构与算法(c++)——查找二叉树与中序遍历的更多相关文章
- 《剑指offer》第八题(重要!查找二叉树的中序遍历的下一个结点)
文件一:main.cpp // 面试题:二叉树的下一个结点 // 题目:给定一棵二叉树和其中的一个结点,如何找出中序遍历顺序的下一个结点? // 树中的结点除了有两个分别指向左右子结点的指针以外,还有 ...
- 数据结构《10》----二叉树 Morris 中序遍历
无论是二叉树的中序遍历还是用 stack 模拟递归, 都需要 O(n)的空间复杂度. Morris 遍历是一种 常数空间 的遍历方法,其本质是 线索二叉树(Threaded Binary Tree), ...
- LeetCode 94:二叉树的中序遍历 Binary Tree Inorder Traversal
题目: 给定一个二叉树,返回它的中序 遍历. Given a binary tree, return the inorder traversal of its nodes' values. 示例: 输 ...
- [LeetCode] Binary Tree Inorder Traversal 二叉树的中序遍历
Given a binary tree, return the inorder traversal of its nodes' values. For example:Given binary tre ...
- LeetCode(94):二叉树的中序遍历
Medium! 题目描述: 给定一个二叉树,返回它的中序 遍历. 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [1,3,2] 进阶: 递归算法很简单,你可以通过迭代算法完成吗 ...
- 【LeetCode题解】94_二叉树的中序遍历
目录 [LeetCode题解]94_二叉树的中序遍历 描述 方法一:递归 Java 代码 Python代码 方法二:非递归 Java 代码 Python 代码 [LeetCode题解]94_二叉树的中 ...
- LeetCode 94. 二叉树的中序遍历(Binary Tree Inorder Traversal)
94. 二叉树的中序遍历 94. Binary Tree Inorder Traversal 题目描述 给定一个二叉树,返回它的 中序 遍历. LeetCode94. Binary Tree Inor ...
- Leetcode题目94.二叉树的中序遍历(中等)
题目描述: 给定一个二叉树,返回它的中序遍历. 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [1,3,2] 进阶: 递归算法很简单,你可以通过迭代算法完成吗? 思路解析: 1 ...
- Java实现 LeetCode 94 二叉树的中序遍历
94. 二叉树的中序遍历 给定一个二叉树,返回它的中序 遍历. 示例: 输入: [1,null,2,3] 1 2 / 3 输出: [1,3,2] 进阶: 递归算法很简单,你可以通过迭代算法完成吗? / ...
随机推荐
- 【树莓派】为树莓派配置或扩展swap分区
---恢复内容开始--- 由于树莓派3的默认内存只有1G,而应用程序运行过程中,存在大量的IO读写,以及网络转换,内存交换等.这样,也有很多buffer.cache资源占用等,很快就会接近1GB,最终 ...
- Memcached for windows x64 x32 安装
Memcached for windows 一.安装Memcached 1.下载 Memcached32位:http://s3.amazonaws.com/downloads.northscale.c ...
- SpringMVC构建Restful。
因为spring是依赖jackson来生成json,需要添加jar包. pom.xml文件添加依赖. <dependency> <groupId>org.codehaus.ja ...
- NioSocket相关知识
一.Nio简介 nio 是non-blocking的简称,在jdk1.4 里提供的新api .Sun 官方标榜的特性如下: 为所有的原始类型提供(Buffer)缓存支持.字符集编码解码解决方案. Ch ...
- /proc/kcore失效,调试其文件系统相关模块,使重新正常工作
为分析内核,在有限的机器上用虚拟机装了CentOS.6.9.i386.minimal,重新编译了3.19.8内核并克隆.当使用/proc/kcore进行内核动态映像调试时,发现与kgdb远程调试端读到 ...
- 5.Lock接口及其实现ReentrantLock
jdk1.7.0_79 在java.util.concurrent.locks这个包中定义了和synchronized不一样的锁,重入锁——ReentrantLock,读写锁——ReadWriteLo ...
- 调整分区大小(ext2\ext3\ext4)
现在的时间是2017年5月27日 我想说调整分区大小没那么麻烦,至少我直接将一个ext3格式分区从50G减少到了30G. 步骤如下 1 首先确保那个分区是没被挂载的. 2 调整分区大小,但是其实并没有 ...
- Managing Spark data handles in R
When working with big data with R (say, using Spark and sparklyr) we have found it very convenient t ...
- Error getting nested result map values for 'company'. Cause: java.sql.SQLException: Invalid value for getInt() - 'NFHK188'
我今天遇到一个我不解的问题,是mybatis多对一关系查询出问题了,但是我自己还是解决了,在网上也查过那个错误,可是找不到我想要的.不知道你们遇到过没有,我接下来分享给大家.希望我这个第一篇博客能帮助 ...
- ECS_8080端口连接拒绝问题排查
原文链接 用户ECS网络设置 上图是用户ECS的网络示意图: ecs处于vpc网络下 ecs加入了一个安全组,该安全组出入方向均开放8080端口 ecs有两个网卡,一个私网主网卡(有虚线的网卡),一个 ...