剑指Offer面试题:7.二叉树的下一个结点
一、题目
————————————————
给定一棵二叉树和其中的一个结点,如何找出中序遍历顺序的下一个结点? 树中的结点除了有两个分别指向左右子结点的指针以外,还有一个指向父结点的指针。
————————————————
二、思路
————————————————
首先自己在草稿纸上画图,进行分析(不再展开)。可以发现下一个结点的规律为:
1.若当前结点有右子树时,其下一个结点为右子树中最左子结点;
2.若当前结点无右子树时,
(1)若当前结点为其父结点的左子结点时,其下一个结点为其父结点;
(2)若当前结点为其父结点的右子结点时,继续向上遍历父结点的父结点,直到找到一个结点是其父结点的左子结点(与(1)中判断相同),该结点即为下一结点。
————————————————
中序遍历,下一个结点有两种情况
a. 当前结点有右子树,就找出右子树中的最左的结点;
b. 当前结点没有右子树 就往它的父节点找,找到第一个结点是它的父节点的左子节点的结点时停止,下一个结点就是该节点的父节点;
作如下表述:
(1):有右子树的,那么下个结点就是右子树最左边的点;
(2):没有右子树的,给出结点是父结点的左孩子,返回父结点;
(3):没有右子树,给出结点是父结点的右孩子,把给出结点的父节点作为下一个遍历的节点,向上回溯,直到当前结点是其父节点的左孩子时停止【直到找到一个父节点X,并且这个父节点X是其本身的父节点Y的左孩子为止】,下一个结点就是当前结点的父节点proot【return proot】。【TreeLinkNode *proot=pNode->next;proot->left==pNode,pNode是当前节点,pNode->next是当前节点的父节点,proot->left是其父结点的左结点】,
例子: 先序遍历:1 2 4 6 7 5 8 3(根左右); 中序遍历:6 4 7 2 5 8 1 3(左根右)【给出的结点为8,下一个结点为1为例】 后序遍历:6 7 4 8 5 2 3 1(左右根)
————————————————
三、解决问题
————————————————
测试用例
1.正常二叉树
2.左斜树、右斜树
4.单个结点
5.null
6.不同位置结点的下一结点(即上面分析的几种情况、无下一节点等情况)
————————————————
package swordoffer;
/**
* @author LQ
* @version 1.0
* @date 2020-03-13 14:24
*/
public class TreeLinkNode {
int val;
TreeLinkNode left = null;
TreeLinkNode right = null;
TreeLinkNode next = null;
TreeLinkNode(int val) {
this.val = val;
}
}
package swordoffer;
/**
* @author LQ
* @version 1.0
* @date 2020-03-13 14:23
*/
/**
* 题目:给定一棵二叉树和其中的一个结点,如何找出中序遍历顺序的下一个结点?
树中的结点除了有两个分别指向左右子结点的指针以外,还有一个指向父结点的指针。
*/
public class Solution07 {
public static void main(String[] args) {
System.out.println("==============================");
Solution07 sword = new Solution07();
sword.test1();
System.out.println("==============================");
sword.test2();
System.out.println("==============================");
sword.test3();
System.out.println("==============================");
sword.test4();
System.out.println("==============================");
}
public TreeLinkNode GetNext(TreeLinkNode pNode) {
if(null == pNode){
System.out.println("结点为null");
return null;
}
//1.若当前结点有右子树时,其下一个结点为右子树中最左子结点--对应图1
if(pNode.right != null){
TreeLinkNode node = pNode.right;
while(node.left != null){
node = node.left;
}
return node;
}else{
//2:没有右子树的,给出结点是父结点的左孩子,返回父结点--对应图2,3
while (pNode.next != null){
TreeLinkNode parent = pNode.next;
if(parent.left == pNode){
return parent;
}
pNode = pNode.next;
}
}
return null;
}
// ==================================测试代码==================================
//创建树较为繁琐,未包括所有测试代码。
public void test1() {
TreeLinkNode node = null;
TreeLinkNode nextNode = GetNext(node);
if(nextNode!=null)
System.out.println(nextNode.val);
else
System.out.println("无下一结点");
}
/**
* 1:有右子树的,那么下个结点就是右子树最左边的点
*/
public void test2() {
TreeLinkNode node1 = new TreeLinkNode(1);
TreeLinkNode node2 = new TreeLinkNode(2);
TreeLinkNode node3 = new TreeLinkNode(3);
TreeLinkNode node4 = new TreeLinkNode(4);
TreeLinkNode node5 = new TreeLinkNode(5);
TreeLinkNode node6 = new TreeLinkNode(6);
node1.left = node2;
node1.right = node3;
node2.next = node1;
node3.next = node1;
node2.left = node4;
node2.right = node5;
node4.next = node2;
node5.next = node2;
node5.left = node6;
node6.next=node5;
TreeLinkNode nextNodeOf1=GetNext(node2);
if(nextNodeOf1!=null)
System.out.println("2结点的下一个结点值为:"+nextNodeOf1.val);
else
System.out.println("2结点无下一结点");
}
/**
* 2:没有右子树的,给出结点是父结点的左孩子,返回父结点;
*/
public void test3() {
TreeLinkNode node1 = new TreeLinkNode(1);
TreeLinkNode node2 = new TreeLinkNode(2);
TreeLinkNode node3 = new TreeLinkNode(3);
TreeLinkNode node4 = new TreeLinkNode(4);
TreeLinkNode node6 = new TreeLinkNode(6);
TreeLinkNode node7 = new TreeLinkNode(7);
node1.left = node2;
node1.right = node3;
node2.next = node1;
node3.next = node1;
node2.left = node4;
node4.next = node2;
node4.left = node6;
node4.right = node7;
node6.next = node4;
node7.next = node4;
TreeLinkNode nextNodeOf1=GetNext(node2);
if(nextNodeOf1!=null)
System.out.println("2结点的下一个结点值为:"+nextNodeOf1.val);
else
System.out.println("2结点无下一结点");
}
/**
* 3:没有右子树,给出结点是父结点的右孩子
* 把给出结点的父节点作为下一个遍历的节点,向上回溯
* 直到当前结点是其父节点的左孩子时停止
* 直到找到一个父节点X,并且这个父节点X是其本身的父节点Y的左孩子为止
*/
public void test4() {
TreeLinkNode node1 = new TreeLinkNode(1);
TreeLinkNode node2 = new TreeLinkNode(2);
TreeLinkNode node3 = new TreeLinkNode(3);
TreeLinkNode node4 = new TreeLinkNode(4);
TreeLinkNode node5 = new TreeLinkNode(5);
TreeLinkNode node6 = new TreeLinkNode(6);
TreeLinkNode node7 = new TreeLinkNode(7);
TreeLinkNode node8 = new TreeLinkNode(8);
node1.left = node2;
node1.right = node3;
node2.next = node1;
node3.next = node1;
node2.left = node4;
node2.right = node5;
node4.next = node2;
node5.next = node2;
node4.left = node6;
node4.right = node7;
node6.next = node4;
node7.next = node4;
node5.right = node8;
node8.next=node5;
TreeLinkNode nextNodeOf1=GetNext(node8);
if(nextNodeOf1!=null)
System.out.println("8结点的下一个结点值为:"+nextNodeOf1.val);
else
System.out.println("8结点无下一结点");
}
}
————————————————
努力也是需要学习的,别再让你的努力,只感动了自己!愿你的每一次努力,都能为自己和别人创造价值。
建立本人的Java基础技术栈积累库
查看9道真题和解析