中序遍歷 左中右 找前驅結點 分類討論左孩子
找后繼結點,分類討論右孩子
現在有一種新的二叉樹節點類型如下:
public class Node {
public int value;
public Node left;
public Node right;
public Node parent;
public Node(int data) {
this.value = data;
}
}
該結構比普通二叉樹節點結構多了一個指向父節點的parent指針。
假設有一 棵Node類型的節點組成的二叉樹, 樹中每個節點的parent指針都正確地指向自己的父節點,頭節點的parent指向null。
只給一個在二叉樹中的某個節點 node, 請實現返回node的后繼節點的函數。
在二叉樹的中序遍歷的序列中, node的下一個節點叫作node的后繼節點。
一種實現方式(很笨的方法):利用node結點的parent指針,找到頭結點,然后利用中序遍歷,找到node結點,然后找到它的下一個結點
public static Node findNextNode(Node node){
if(node == null) return null;
Node head = node;
//找到頭結點
while(head.parent != null){
head = head.parent;
}
List<Node> nodeList = new ArrayList<>();
inOrder(head, nodeList);
System.out.print("中序遍歷結果:");
for(Node n : nodeList){
System.out.print(n.value + " ");
}
System.out.println();
int index = nodeList.indexOf( node );
return nodeList.get(index + 1);
}
public static void inOrder(Node node, List<Node> nodeList){
if(node == null) return;
inOrder(node.left, nodeList);
nodeList.add(node);
inOrder(node.right, nodeList);
}
另外一種實現方式:
可以將該結點分為兩種情況,
1.沒有右子樹,那它是某一個左子樹的最后一個結點,然后找到這個左子樹的parent即可
找它的parent,直到當前節點是parent的左子樹為止
2.有右子樹,那它的下一個結點就是它的右子樹的最左的結點(若它的右子樹沒有左子樹,那就是右子樹本身)
public static Node findNextNode1(Node node){
if(node == null) return null;
//當前節點沒有右子樹
if(node.right == null) {
Node parentNode = node.parent;
while(parentNode != null && parentNode.left != node){
node = parentNode;
parentNode = node.parent;
}
return parentNode;
} else{
node = node.right;
while(node.left != null){
node = node.left;
}
return node;
}
}
