✅作者简介:热爱后端语言的大学生,CSDN内容合伙人
✨精品专栏:C++面向对象
🔥系列专栏:剑指offer
📃推荐一款模拟面试、刷题神器👉注册免费刷题
本篇文章给大家分享牛客网《剑指offer》专栏中有关二叉树的经典算法题解,我会按照自己的理解与思路帮助大家搞懂算法流程。
1. 我们首先要根据给定输入中的结点指针向父级进行迭代,直到找到该树的根节点;
2. 然后根据根节点进行中序遍历,当遍历到和给定树节点相同的节点时,下一个节点就是我们的目标返回节点
具体步骤:
/*
struct TreeLinkNode {
int val;
struct TreeLinkNode *left;
struct TreeLinkNode *right;
struct TreeLinkNode *next;
TreeLinkNode(int x) :val(x), left(NULL), right(NULL), next(NULL) {
}
};
*/
class Solution {
public:
vector<TreeLinkNode*>nodes;
TreeLinkNode* GetNext(TreeLinkNode* pNode) {
TreeLinkNode* root=pNode;
//利用父指针找到根结点
while(root->next)
root=root->next;
//调用中序遍历
InOrder(root);
int num=nodes.size();
for(int i=0;i<num;i++){
TreeLinkNode *cur=nodes[i];
if(pNode==cur){
return nodes[i+1];
}
}
return NULL;
}
//书写中序遍历
void InOrder(TreeLinkNode* root){
if(root==NULL) return;
InOrder(root->left);
nodes.push_back(root);
InOrder(root->right);
}
};
nodes
,注意是创建在方法外部,目的是可以在类内任意使用root
结点并借助while
循环通过父指针next
找到根结点InOrder
中序遍历函数,将中序遍历结果存入上方创建的nodes
数组中for
循环将传入结点pNode
与数组元素比较,如果匹配到就返回位置加一的结点
前序遍历的时候我们采用的是“根左右”的遍历次序,如果这棵二叉树是对称的,即相应的左右节点交换位置完全没有问题;
那我们是不是可以尝试“根右左”遍历,按照轴对称图像的性质,这两种次序的遍历结果应该是一样的。
但是如果相同的方式进行两次,可行但我们不去做,这对时间的消耗太多了,我们不如在遍历的过程就结果比较了。而遍历方式依据前序递归可以使用递归:
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};
*/
class Solution {
public:
bool isSymmetrical(TreeNode* pRoot) {
return dgfunc(pRoot,pRoot);
}
bool dgfunc(TreeNode* root1,TreeNode* root2){
if(root1==NULL&&root2==NULL)
return true;
if(root1==NULL||root2==NULL||root1->val!=root2->val)
return false;
return dgfunc(root1->left, root2->right) && dgfunc(root1->right,root2->left);
}
};
dgfunc
函数,将pRoot
传入比较true
NULL
或者左子树与右子树不同,返回false
true
,不相同则返回false
还是那句话,牵扯到二叉树就尽量使用递归的方法来解决问题!