中序遍歷 左中右 找前驅結點 分類討論左孩子
找后繼結點,分類討論右孩子
現在有一種新的二叉樹節點類型如下:
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; } }