题目:二叉树的下一个结点
题目描述
给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。
思路:
①有右子树:找右子树的左孩子
无右子树:找父节点的left是node,否则node=node->next;找到根节点都找不到就返回NULL(可能是最后一个)
/*
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:
TreeLinkNode* GetNext(TreeLinkNode* pNode)
{
//有右子树:找右子树的左孩子
if(pNode->right!=NULL){
pNode = pNode->right;
while(pNode->left!=NULL) pNode=pNode->left;
return pNode;
}
//无右子树:找父节点的left是node,否则node=node->next;
else{
while(pNode->next!=NULL){
if(pNode->next->left==pNode) return pNode->next;
else pNode = pNode->next;
}
}
//都找不到就应该是最后一个节点,返回NULL
return NULL;
}
};
②找到根节点,进行中序遍历,遍历时找到目标节点,返回目标节点的下一个节点
/*
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:
TreeLinkNode *answer=NULL;//返回目标节点
int flag=0;//记录pNode是否找到
void inorderTraversal(TreeLinkNode *root, TreeLinkNode *pNode){
if(root!=NULL){
inorderTraversal(root->left, pNode);
if(flag==1 && !answer) answer=root;
if(root==pNode){
flag = 1;
}
inorderTraversal(root->right, pNode);
}
return ;
}
TreeLinkNode* GetNext(TreeLinkNode* pNode)
{
TreeLinkNode *root=pNode;
//找到根节点所在位置
while(root->next!=NULL){
root = root->next;
}
// 中序遍历
inorderTraversal(root, pNode);
return answer;
}
};
测试代码:
#include<iostream>
#include<vector>
#include<queue>
#include<stack>
using namespace std;
struct TreeNode{
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x):
val(x), left(NULL), right(NULL){
}
};
class Solution{
public:
// 思路:递归左右子树,找出左右的pre和vin
TreeNode *reConstructBinaryTree(vector<int> pre, vector<int> vin){
int mid, size=pre.size();
if(size==0) return NULL;
TreeNode *root = new TreeNode(pre[0]);
// 找mid的位置
for(int i=0;i<size;i++){
if(pre[0]==vin[i]){
mid=i;break;
}
}
// 定义l_pre,l_vin,r_pre,r_vin;
vector<int> l_pre,l_vin,r_pre,r_vin;
for(int i=0;i<mid;i++){
l_pre.push_back(pre[i+1]);
l_vin.push_back(vin[i]);
}
for(int i=mid+1;i<size;i++){
r_pre.push_back(pre[i]);
r_vin.push_back(vin[i]);
}
//递归找出左右子树
root->left = reConstructBinaryTree(l_pre, l_vin);
root->right = reConstructBinaryTree(r_pre, r_vin);
return root;
}
TreeNode *answer=NULL;
int flag=0;
void inorderTraversal(TreeNode *root, TreeNode *pNode){
if(root){
inorderTraversal(root->left, pNode);
cout<<root->val<<" "<<endl;
if(flag==1 && answer==NULL) {
answer=root;
cout<<"目标节点 :"<<answer->val<<endl;
}
if(root==pNode){
flag = 1;
cout<<"已找到pNode节点 :"<<root->val<<endl;
}
inorderTraversal(root->right, pNode);
}
return ;
}
TreeNode* GetNext(TreeNode* pNode)
{
TreeNode *root=pNode;
// while(pNode->next!=NULL) root = pNode;
inorderTraversal(root, pNode->left->left);
return answer;
}
};
int main(){
vector<int>p={8,6,5,7,10,9,11}, v={5,6,7,8,9,10,11};
Solution s;
//建树
TreeNode *r = s.reConstructBinaryTree(p,v);
cout<<r->left->left->val<<endl;
r = s.GetNext(r);
cout<<r->val<<endl;
return 0;
}