数据结构与算法(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] 进阶: 递归算法很简单,你可以通过迭代算法完成吗? / ...
随机推荐
- springboot(十二):springboot如何测试打包部署
有很多网友会时不时的问我,spring boot项目如何测试,如何部署,在生产中有什么好的部署方案吗?这篇文章就来介绍一下spring boot 如何开发.调试.打包到最后的投产上线. 开发阶段 单元 ...
- UI-UIwindow
1.什么是UI? UI (User Interface) : 用户界面,用户看到的各种各样的页面元素: 2.什么是UIWindow ? UIWindow : 一个基础容器,往窗口上放不同的东西,每个 ...
- 【SoDiaoEditor电子病历编辑器】阶段性更新啦
转眼距离上一次v2正式发布已经过去一个半月了.github期间不定期push了二十几次,同时感谢分布在广州.福建.上海.北京的一众小伙伴,正是你们给出的建议,才让SoDiaoEditor不断完善. 我 ...
- Python爬虫学习之获取网页源码
偶然的机会,在知乎上看到一个有关爬虫的话题<利用爬虫技术能做到哪些很酷很有趣很有用的事情?>,因为强烈的好奇心和觉得会写爬虫是一件高大上的事情,所以就对爬虫产生了兴趣. 关于网络爬虫的定义 ...
- swift学习 - collectionView
swift CollectionView学习 效果图: 源码: ContModel.swift import UIKit class ContModel: NSObject { var title:S ...
- .net操作InI文件
public class INI { public static string IniFileName = "";//路径 [DllImport("kernel32&qu ...
- JS 一条原型链扯到底
在正文之前,首先要知道两点, 1.__proto__是每个js 对象的内置属性,而prototype 是函数的内置属性,也是一个对象. 2.所谓原型,指的就是每个函数对象的prototype属性. f ...
- springboot thymeleaf和shiro标签整合
这里用的是 thymeleaf 2.x版本的 添加依赖 <dependency> <groupId>com.github.theborakompanioni</group ...
- JDFS:一款分布式文件管理实用程序第二篇(更新升级、解决一些bug)
一 前言 本文是<JDFS:一款分布式文件管理实用程序>系列博客的第二篇,在上一篇博客中,笔者向读者展示了JDFS的核心功能部分,包括:服务端与客户端部分的上传.下载功能的实现,epoll ...
- javascript获取json对象的key名称的两种方法
javascript获取json对象的key名称的两种方法 数据处理中,你可能接收到一个不确定内容格式的json对象,然后要把key的值提取出来.今天试过两种可以提取json key的方法,均可以正常 ...