您的位置:首页 > 职场人生

剑指offer 面试题58 二叉树的下一个结点

2017-06-18 19:45 567 查看

剑指offer 面试题58 二叉树的下一个结点

题目:

给定一棵二叉树和其中的一个结点,如何找出中序遍历顺序的下一个结点?

树中的结点除了有两个分别指向左右子结点的指针以外,还有一个指向父结点的指针。

例如,下图的中序遍历序列为 3, 1, 7, 4, 8, 0, 5, 2, 6。

0
/   \
1     2
/ \   / \
3  4  5   6
/ \
7   8


package algorithm.foroffer.top60;

import org.junit.Test;

/**
* description:
*
* @author liyazhou
* @create 2017-06-18 15:32
*
* 面试题58:二叉树的下一个结点
*
* 题目:
*      给定一棵二叉树和其中的一个结点,如何找出中序遍历顺序的下一个结点?
*      树中的结点除了有两个分别指向左右子结点的指针以外,还有一个指向父结点的指针。
*      例如,下图的中序遍历序列为 3, 1, 7, 4, 8, 0, 5, 2, 6。
*                  0
*                /   \
*               1     2
*              / \   / \
*             3  4  5   6
*               / \
*              7   8
*
*
* 考查点:
*      1. 二叉树的遍历
*
* 思路:
*      1. 中序遍历序列,
*         当前结点有右孩子,则其右子树的最左子结点即是下一个结点
*         当前结点没有右孩子,而且是其父结点的左孩子,则其父结点即是下一个结点
*         当前结点没有左孩子,而且是其父结点的右孩子,则其从下往上的祖先结点中是左孩子的结点即是下一个结点,可能不存在
*
*/

class Node58{
int value;
Node58 parent;
Node58 left;
Node58 right;

public Node58(int _value){ value = _value; }
public void setParentAndChildren(Node58 _parent, Node58 _left, Node58 _right){
parent = _parent;
left = _left;
right = _right;
}
@Override
public String toString(){
return String.format("value = %s", value);
}
}
public class Test58 {

public Node58 nextNode(Node58 node){
if (node == null) return null;
Node58 next = null;

if (node.right != null){   // 当前结点有右孩子,则下一个结点是其右子树的最左子结点
Node58 currNode = node.right;
for (; currNode.left != null; currNode = currNode.left);
next = currNode;
} else if (node.parent != null){ // 当前结点没有右孩子,但存在父结点
Node58 parentNode = node.parent;   // 初始默认当前结点是其父结点的左孩子,则下一个结点就是其父结点
Node58 currNode = node;
// 若当前结点是父结点的右孩子,则一直向上遍历,直到遇到其祖先结点是一个左孩子的情况
// 该祖先结点的父结点的左子树已被遍历完成,则中序遍历的下一个结点就是其父结点
while (parentNode != null && currNode == parentNode.right){
currNode = parentNode;
parentNode = parentNode.parent;
}
next = parentNode;
}

return next;
}

@Test
/**
*                  0
*                /   \
*               1     2
*              / \   / \
*             3  4  5   6
*               / \
*              7   8
*
* 其中序遍历序列为 3, 1, 7, 4, 8, 0, 5, 2, 6。
*/
public void test(){
Node58 node0 = new Node58(0);
Node58 node1 = new Node58(1);
Node58 node2 = new Node58(2);
Node58 node3 = new Node58(3);
Node58 node4 = new Node58(4);
Node58 node5 = new Node58(5);
Node58 node6 = new Node58(6);
Node58 node7 = new Node58(7);
Node58 node8 = new Node58(8);

node0.setParentAndChildren(null, node1, node2);
node1.setParentAndChildren(node0, node3, node4);
node2.setParentAndChildren(node0, node5, node6);
node3.setParentAndChildren(node1, null, null);
node4.setParentAndChildren(node1, node7, node8);
node5.setParentAndChildren(node2, null, null);
node6.setParentAndChildren(node2, null, null);
node7.setParentAndChildren(node4, null, null);
node8.setParentAndChildren(node4, null, null);

System.out.println(0 + " -> " + nextNode(node0));
System.out.println(1 + " -> " + nextNode(node1));
System.out.println(2 + " -> " + nextNode(node2));
System.out.println(3 + " -> " + nextNode(node3));
System.out.println(4 + " -> " + nextNode(node4));
System.out.println(5 + " -> " + nextNode(node5));
System.out.println(6 + " -> " + nextNode(node6));
System.out.println(7 + " -> " + nextNode(node7));
System.out.println(8 + " -> " + nextNode(node8));

/**
0 -> value = 5
1 -> value = 7
2 -> value = 6
3 -> value = 1
4 -> value = 8
5 -> value = 2
6 -> null
7 -> value = 4
8 -> value = 0
*/
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: