【剑指offer】25.二叉树的下一个结点

总目录:

算法之旅导航目录

 

1.问题描述

 给定一个二叉树其中的任意一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的next指针。

数据范围:节点数满足 1≤n≤50,节点上的值满足 1≤val≤100
要求:空间复杂度 O(1) ,时间复杂度 O(n)

输入:整体二叉树为{8,6,10,5,7,9,11},输入节点为8,按中序搜索的顺序,则返回值:9

输入:整体二叉树为{8,6,10,5,7,9,11},输入节点为6,按中序搜索的顺序,则返回值:7

 

2.问题分析

 1递归

首先要清楚输入的节点是树上任意一个节点,

然后要清楚要找的是中序遍历顺序中目标节点的下一个节点,

因此需要先整树中序遍历到目标节点,然后继续遍历,借用等待标志位取下一个非空节点

2强行迭代

需要梳理出不同状况,层序分流,共分为四种情况

  1. 如果给出的结点有右子节点,则最终要返回的下一个结点即右子树的最左下的结点
  2. 如果给出的结点无右子节点,且当前结点是其父节点的左子节点,则返回其父节点
  3. 如果给出的结点无右子节点,且当前结点是其父节点的右子节点,则先要沿着左上方父节点爬树,一直爬到当前结点是其父节点的左子节点为止,返回的就是这个父节点;
  4. 或者没有满足上述情况的则返回为NULL


3.代码实例

递归

 1 class Solution {
 2   public:
 3     bool isWaitting;//是否处于等待状态
 4     TreeLinkNode* pTgtNode;//记录目标节点
 5     TreeLinkNode* GetNext(TreeLinkNode* pNode) {
 6         //空节点不予处理
 7         if (!pNode) {
 8             return NULL;
 9         }
10 
11         //标记目标节点和等待状态
12         pTgtNode = pNode;
13         isWaitting = false;
14 
15         //获得整个树的根节点
16         TreeLinkNode* root = pNode;
17         while (root->next) {
18             root = root->next;
19         }
20 
21         //整树搜索获得目标节点,搜索到后置为等待状态,等待下一个非空节点
22         return GetTarget(root);
23     }
24 
25     TreeLinkNode* GetTarget(TreeLinkNode* root) {
26         //终止条件
27         if (!root) {
28             return NULL;
29         }
30 
31         //中序遍历中先检查左侧
32         //先看左树是否符合
33         TreeLinkNode* pCur = NULL;
34         pCur = GetTarget(root->left);
35         if (pCur) {
36             return pCur;
37         }
38 
39         //中序遍历的中
40         //是否在等待,如果在等立即将本节点返回
41         if (isWaitting) {
42             return root;
43         }
44         //是否要置起等待状态
45         if (root == pTgtNode) {
46             isWaitting = true;
47         }
48 
49         //中序遍历的右
50         //查看右树是否符合
51         pCur = GetTarget(root->right);
52         if (pCur) {
53             return pCur;
54         }
55 
56         return NULL;
57     }
58 };
View Code

迭代

 1 class Solution {
 2 public:
 3     TreeLinkNode* GetNext(TreeLinkNode* pNode) {
 4         // 如果有右子树
 5         if(pNode->right) {    
 6             TreeLinkNode* rchild = pNode->right;
 7             // 一直找到右子树的最左下的结点为返回值
 8             while(rchild->left) rchild = rchild->left;    
 9             return rchild;
10         }
11         // 如果无右子树且当前结点是其父节点的左子结点
12         if(pNode->next && pNode->next->left == pNode) {    
13             // 返回当前结点的父节点
14             return pNode->next;   
15         }
16         // 如果无右子树且当前结点是其父节点的右子节点
17         if(pNode->next) {         
18             TreeLinkNode* ppar = pNode->next;
19             // 沿着左上一直爬树,爬到当前结点是其父节点的左自己结点为止
20             while(ppar->next && ppar->next->right == ppar) ppar = ppar->next;    
21             // 返回当前结点的父节点
22             return ppar->next;    
23         }
24         return NULL;
25     }
26 };
View Code

 

posted @ 2022-11-13 14:13  啊原来是这样呀  阅读(23)  评论(0编辑  收藏  举报