尋找二叉樹上從根結點到給定結點的路徑
阿新 • • 發佈:2020-09-08
1.遞迴實現
public static boolean searchNode(TreeNode root,Stack<TreeNode> s,TreeNode node) { if(root == null) return false; s.push(root); if(root.val == node.val) return true; boolean b = false; //先去左子樹找 if(root.left != null) b = searchNode(root.left,s,node);//左子樹找不到並且右子樹不為空的情況下才去找 if(!b && root.right != null) b = searchNode(root.right,s,node); //左右都找不到,彈出棧頂元素 if(!b) s.pop(); return b; }
2.非遞迴實現
思想:這個稍微有些複雜,當然也是要藉助棧來完成。其實這裡和二叉樹的非遞迴先序遍歷的思想差不多,只是在這個基礎上進行一些改造。首先,新建一個棧,儲存根節點。然後開始一直向左查詢,查詢的過程中把結點入棧。如果在向左找的過程中遇到了給定的結點,那麼就輸出並返回,這個過程比較好理解。關鍵是下面的彈棧的過程,如果在向左找的過程中遇到了null,說明當前棧頂元素的左子樹為null。那麼我們向棧頂元素的右子樹開始查詢。令p為棧頂元素,如果棧頂元素的右子樹為null,那麼彈出棧頂元素,並用pre來儲存剛彈出的元素,之所以設定pre,是因為如果當前棧頂元素的右子樹不為null的時候,不能輕易彈出,首先得去右子樹上去查詢,如果右孩子被彈出了,說明右子樹上肯定沒有,那麼當前結點才可以彈出。
public static void searchNode(TreeNode root,TreeNode node) { if(root == null || node == null) return; Stack<TreeNode> s = new Stack<>(); TreeNode p = root; TreeNode pre = null; //上一次出棧的結點 while(p != null || !s.isEmpty()) { while(p != null) { //這個while迴圈的思想還是一直往左找,找的過程結點入棧,如果找到了就列印輸出並返回。 s.push(p); if(p.val == node.val) { for (TreeNode treeNode : s) { System.out.print(treeNode.val + " "); } return; } p = p.left; } //走到這一步說明棧頂元素的左子樹為null,那麼就開始往棧頂元素的右子樹上去找。 if(!s.isEmpty()) { p = s.peek(); //如果棧頂元素的右子樹為null,或者右子樹被遍歷過,則彈棧。 while(p.right == null || pre != null && p.right == pre) { pre = s.pop(); p = s.peek(); } //繼續遍歷p的右子樹 p = p.right; } } }