题目:给定一颗二叉树和其中的一个节点,如何找出中序遍历的下一个节点?树中的节点除了有两个分别指向左,右子节点的指针,还有一个指向父节点的指针。(二叉树如下图所示)
中序遍历:{d,b,h,e,i,a,f,c,g}
分析: 考虑中序遍历的特点以及下一个节点可能出现的情况
1. 节点的左子树不可能有下一节点(中序遍历)
2. 节点的右子树存在时,其右子树的最左子节点就是下一节点
3.节点没有右子树时,如果当前节点是其父节点的左子节点,则父节点为下一节点
4. 节点没有右子树时,如果当前节点是其父节点的右子节点,则需要继续向上寻找父节点,直到满足条件3
Android 端代码的实现:----代码中有详细的注释
/**
* 根据给出的节点,找到在--中序遍历--中的下一个节点
*
* @param targetNode
* @return
*/
private TreeNode getNextNode(TreeNode targetNode) {
TreeNode nextNode = null;
if (targetNode == null) {
// 如果目标节点不存在,则返回null
return nextNode;
}
/**
* 中序遍历中当前节点的下一个节点不会出现在左子树上
* 如果当前节点有右子树,则【下一个节点】必定是右子树的最左的那个节点
* 如果当前节点没有右子树,1. 如果该节点为其父节点的左子节点,则其
* 父节点就是【下一个节点】 2 如果该节点为其父节点的右子节点,则需要
* 一直向上寻找父节点,直到子节点为其父节点的左子节点为止,则其父节点
* 就是【下一个节点】
*/
TreeNode rightNode = targetNode.getRight();
if (rightNode != null) {
// 如果目标节点的右子树不为空,则寻找其最左节点
while (rightNode.getLeft() != null) {
rightNode = rightNode.getLeft();
}
nextNode = rightNode;
} else if (targetNode.getParent() != null) {
// 如果目标节点的右子树为空,则遍历其父节点
TreeNode parentNode = targetNode.getParent();
while (parentNode != null && targetNode == parentNode.getRight()) {
// 如果父节点不为空且当前的目标节点值为父节点的右子树,则继续循环
// 将当前的父节点赋给目标节点,
targetNode = parentNode;
// 找到当前父节点的父节点
parentNode = parentNode.getParent();
}
/**
* 跳出循环条件:
* parentNode == null, 下一个节点不存在
* targetNode != parentNode.getRight() 目标节点不是父节点的右子树
*/
nextNode = parentNode;
}
return nextNode;
}