剑指offer笔记面试题8----二叉树的下一个节点
题目:给定一棵二叉树和其中的一个节点,如何找出中序遍历序列的下一个节点?树中的节点除了有两个分别指向左、右子节点的指针,还有一个指向父节点的指针。
测试用例:
- 普通二叉树(完全二叉树,不完全二叉树)。
- 特殊二叉树(所有节点都没有右子节点的二叉树;所有节点都没有左子节点的二叉树;只有一个节点的二叉树;二叉树的根节点指针为nullptr)。
- 不同位置的节点的下一个节点(下一个节点为当前节点的右子节点、右子树的最左子节点、父节点、跨层的父节点等;当前节点没有下一个节点)。
测试代码:
void Test(char* testName, BinaryTreeNode* pNode, BinaryTreeNode* expected)
{
if(testName != nullptr)
printf("%s begins: ", testName);
BinaryTreeNode* pNext = GetNext(pNode);
if(pNext == expected)
printf("Passed.\n");
else
printf("FAILED.\n");
}
// 8
// 6 10
// 5 7 9 11
void Test1_7()
{
BinaryTreeNode* pNode8 = CreateBinaryTreeNode(8);
BinaryTreeNode* pNode6 = CreateBinaryTreeNode(6);
BinaryTreeNode* pNode10 = CreateBinaryTreeNode(10);
BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
BinaryTreeNode* pNode7 = CreateBinaryTreeNode(7);
BinaryTreeNode* pNode9 = CreateBinaryTreeNode(9);
BinaryTreeNode* pNode11 = CreateBinaryTreeNode(11);
ConnectTreeNodes(pNode8, pNode6, pNode10);
ConnectTreeNodes(pNode6, pNode5, pNode7);
ConnectTreeNodes(pNode10, pNode9, pNode11);
Test("Test1", pNode8, pNode9);
Test("Test2", pNode6, pNode7);
Test("Test3", pNode10, pNode11);
Test("Test4", pNode5, pNode6);
Test("Test5", pNode7, pNode8);
Test("Test6", pNode9, pNode10);
Test("Test7", pNode11, nullptr);
DestroyTree(pNode8);
}
// 5
// 4
// 3
// 2
void Test8_11()
{
BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4);
BinaryTreeNode* pNode3 = CreateBinaryTreeNode(3);
BinaryTreeNode* pNode2 = CreateBinaryTreeNode(2);
ConnectTreeNodes(pNode5, pNode4, nullptr);
ConnectTreeNodes(pNode4, pNode3, nullptr);
ConnectTreeNodes(pNode3, pNode2, nullptr);
Test("Test8", pNode5, nullptr);
Test("Test9", pNode4, pNode5);
Test("Test10", pNode3, pNode4);
Test("Test11", pNode2, pNode3);
DestroyTree(pNode5);
}
// 2
// 3
// 4
// 5
void Test12_15()
{
BinaryTreeNode* pNode2 = CreateBinaryTreeNode(2);
BinaryTreeNode* pNode3 = CreateBinaryTreeNode(3);
BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4);
BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
ConnectTreeNodes(pNode2, nullptr, pNode3);
ConnectTreeNodes(pNode3, nullptr, pNode4);
ConnectTreeNodes(pNode4, nullptr, pNode5);
Test("Test12", pNode5, nullptr);
Test("Test13", pNode4, pNode5);
Test("Test14", pNode3, pNode4);
Test("Test15", pNode2, pNode3);
DestroyTree(pNode2);
}
void Test16()
{
BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
Test("Test16", pNode5, nullptr);
DestroyTree(pNode5);
}
本题考点:
- 考查应聘者对二叉树中序遍历的理解程度。只有对二叉树的遍历算法有了深刻的理解,应聘者才有可能准确找出每个节点的中序遍历的下一个节点。
- 考查应聘者分析复杂问题的能力。应聘者只有画出二叉树的结构图、通过具体的例子找出中序遍历下一个节点的规律,才有可能设计出可行的算法。
实现代码:
#include <cstdio>
struct BinaryTreeNode
{
int m_nValue;
BinaryTreeNode* m_pLeft;
BinaryTreeNode* m_pRight;
BinaryTreeNode* m_pParent;
};
BinaryTreeNode* GetNext(BinaryTreeNode* pNode)
{
if(pNode == nullptr)
return nullptr;
BinaryTreeNode* pNext = nullptr;
if(pNode->m_pRight != nullptr)
{
BinaryTreeNode* pRight = pNode->m_pRight;
while(pRight->m_pLeft != nullptr)
pRight = pRight->m_pLeft;
pNext = pRight;
}
else if(pNode->m_pParent != nullptr)
{
BinaryTreeNode* pCurrent = pNode;
BinaryTreeNode* pParent = pNode->m_pParent;
while(pParent != nullptr && pCurrent == pParent->m_pRight)
{
pCurrent = pParent;
pParent = pParent->m_pParent;
}
pNext = pParent;
}
return pNext;
}
// ==================== 辅助代码用来构建二叉树 ====================
BinaryTreeNode* CreateBinaryTreeNode(int value)
{
BinaryTreeNode* pNode = new BinaryTreeNode();
pNode->m_nValue = value;
pNode->m_pLeft = nullptr;
pNode->m_pRight = nullptr;
pNode->m_pParent = nullptr;
return pNode;
}
void ConnectTreeNodes(BinaryTreeNode* pParent, BinaryTreeNode* pLeft, BinaryTreeNode* pRight)
{
if(pParent != nullptr)
{
pParent->m_pLeft = pLeft;
pParent->m_pRight = pRight;
if(pLeft != nullptr)
pLeft->m_pParent = pParent;
if(pRight != nullptr)
pRight->m_pParent = pParent;
}
}
void PrintTreeNode(BinaryTreeNode* pNode)
{
if(pNode != nullptr)
{
printf("value of this node is: %d\n", pNode->m_nValue);
if(pNode->m_pLeft != nullptr)
printf("value of its left child is: %d.\n", pNode->m_pLeft->m_nValue);
else
printf("left child is null.\n");
if(pNode->m_pRight != nullptr)
printf("value of its right child is: %d.\n", pNode->m_pRight->m_nValue);
else
printf("right child is null.\n");
}
else
{
printf("this node is null.\n");
}
printf("\n");
}
void PrintTree(BinaryTreeNode* pRoot)
{
PrintTreeNode(pRoot);
if(pRoot != nullptr)
{
if(pRoot->m_pLeft != nullptr)
PrintTree(pRoot->m_pLeft);
if(pRoot->m_pRight != nullptr)
PrintTree(pRoot->m_pRight);
}
}
void DestroyTree(BinaryTreeNode* pRoot)
{
if(pRoot != nullptr)
{
BinaryTreeNode* pLeft = pRoot->m_pLeft;
BinaryTreeNode* pRight = pRoot->m_pRight;
delete pRoot;
pRoot = nullptr;
DestroyTree(pLeft);
DestroyTree(pRight);
}
}
int main(int argc, char* argv[])
{
Test1_7();
Test8_11();
Test12_15();
Test16();
}
剑指offer笔记面试题8----二叉树的下一个节点的更多相关文章
- 【剑指offer】面试题 8. 二叉树的下一个结点
面试题 8. 二叉树的下一个结点 NowCoder 题目描述 给定一棵二叉树和其中的一个结点,如何找出中序遍历顺序的下一个结点?树中的结点除了有两个分别指向左右子结点的指针以外,还有一个指向父结点的指 ...
- 剑指Offer(书):二叉树的下一个节点
题目:给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回.注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针. 分析:若一个节点有右子树,那么他的下一个节点就是他右子树中 ...
- 《剑指offer》面试题39 二叉树的深度(java)
摘要: 今天翻到了<剑指offer>面试题39,题目二中的解法二是在函数的参数列表中通过指针的方式进行传值,而java是没有指针的,所以函数要进行改造.然而我翻了下别人的java版本(我就 ...
- 剑指offer笔记面试题7----重建二叉树
题目:输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如,输入前序遍历序列{1, 2, 4, 7, 3, 5, 6, 8}和中序遍历序列 ...
- 【剑指offer】面试题 55. 二叉树的深度
面试题 55. 二叉树的深度 题目一:二叉树的深度 题目描述:输入一棵二叉树,求该树的深度.从根结点到叶结点依次经过的结点(含根.叶结点)形成树的一条路径,最长路径的长度为树的深度. Java 实现 ...
- 【剑指offer】面试题 23. 链表中环的入口节点
面试题 23. 链表中环的入口节点
- 《剑指Offer》面试题-重建二叉树
题目描述: 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7 ...
- 《剑指offer》面试题25 二叉树中和为某一值的路径 Java版
(判断是否有从根到叶子节点的路径,其和为给定值.记录这些路径.) 我的方法:这道题我是按照回溯的思路去做的,我们需要一个数据结构来保存和删除当前递归函数中添加的值.这里要打印一条路径,我们可以选择Li ...
- 《剑指offer》面试题19 二叉树的镜像 Java版
书中方法:这道题目可能拿到手没有思路,我们可以在纸上画出简单的二叉树来找到规律.最后我们发现,镜像的实质是对于二叉树的所有节点,交换其左右子节点.搞清楚获得镜像的方法,这道题实际上就变成了一道二叉树遍 ...
随机推荐
- Spring Boot 整合 Druid
Spring Boot 整合 Druid 概述 Druid 是阿里巴巴开源平台上的一个项目,整个项目由数据库连接池.插件框架和 SQL 解析器组成.该项目主要是为了扩展 JDBC 的一些限制,可以让程 ...
- Java 将Excel转为PDF
本文将介绍在Java程序中如何将Excel工作簿转为PDF文档的,包括: 将整个工作簿转为PDF 将指定工作表转为PDF 使用工具:Free Spire.XLS for Java (免费版) Ja ...
- 鲲鹏来了,在EulerOS试用.NETCore-3.1
在EulerOS试用.NETCore-3.1 前言 EulerOS其实出来有一段时间了,一直在关注,单是仅仅也只是停留在观望的阶段,目前还没有接入的打算:正好看到园子里的兄弟分享了华为云免费试用的活动 ...
- [TimLinux] JavaScript 如何在html标签的data-*属性使用JSON数据
1. HTML data-*属性 H5引入的data-*属性,可以在JavaScript通过.dataset.*的方式来获取属性的值,例如: /* HTML标签: * <input id=&qu ...
- HDU1517 Multiply Game
Stan and Ollie play the game of multiplication by multiplying an integer p by one of the numbers 2 t ...
- 【Go入门学习】理解区分数组和切片
一.前言 学过 Go 的都知道在 Go 语言中有四种复合数据类型:数组.切片(Slice).哈希表(Map)和结构体(Struct),而很多 Go 初学者也很容易把数组和切片弄混淆,所以要怎么把这两个 ...
- Vue 02
目录 表单指令v-model 条件指令v-if 循环指令v-for 分隔符delimiters 过滤器filters 计算属性computed 监听属性watch 前端数据库 表单指令v-model ...
- 【搞定Jvm面试】 面试官:谈谈 JVM 类文件结构的认识
类文件结构 一 概述 在 Java 中,JVM 可以理解的代码就叫做字节码(即扩展名为 .class 的文件),它不面向任何特定的处理器,只面向虚拟机.Java 语言通过字节码的方式,在一定程度上解决 ...
- 使用VS code 创建 Azure Functions,从blob触发,解析,发送至Service Bus
更多内容,关注公众号:来学云计算 场景: 某设备定时于每天23:00左右将一天的运行日志.devicelogtxt上传到Azure Blob,期待Blob文件上传后, 自动通过Azure Functi ...
- 设备数据通过Azure Functions 推送到 Power BI 数据大屏进行展示(2.Azure Functions实战)
本案例适用于开发者入门理解Azure Functions/ IoT Hub / Service Bus / Power BI等几款产品. 主要实战的内容为: 将设备遥测数据上传到物联网中心, 将遥测数 ...