二叉樹——判斷是否是搜尋二叉樹和完全二叉樹
阿新 • • 發佈:2022-05-12
1. 判斷一棵二叉樹是否為搜尋二叉樹和完全二叉樹
1.1. 問題
給定二叉樹的一個頭節點 head,已知其中沒有重複值的節點,實現兩個函式分別判斷這棵二叉樹是否為搜尋二叉樹和完全二叉樹。
1.2. 思路
判斷是否是搜尋二叉樹可用中序遍歷一遍,倘若是遞增序列,則為搜尋二叉樹。
判斷是否是完全二叉樹:
-
方法一:可以用層序遍歷(廣度優先),當發現一個節點的左子節點或右子節點為空時,那麼接下來都不能在遇到子節點。
-
方法二:可以用深度優先搜尋。一個完全二叉樹可以表示為一個堆,我們在進行遍歷的時候給二叉樹的節點進行編號,然後將最大編號跟節點數量進行比較,如果相同則是完全二叉樹,不同那麼則不是。
判斷一個樹是否為完全搜尋二叉樹時,可以將判斷搜尋二叉樹的方法和判斷完全二叉樹的方法二進行合併。
1.3. 程式碼
1.3.1. 判斷是否為搜尋二叉樹
手動用棧模擬:
public static boolean isBST(TreeNode<Integer> root) { if (root == null) return true; Stack<TreeNode<Integer>> stack = new Stack<>(); TreeNode<Integer> cur = root; TreeNode<Integer> pre = null; while (!stack.empty() || cur != null) { if (cur != null) { stack.push(cur); cur = cur.left; } else { cur = stack.pop(); if (pre != null && pre.val > cur.val) return false; pre = cur; cur = cur.right; } } return true; }
遞迴:
class Solution { private long previousNodeVal = Long.MIN_VALUE; public boolean isValidBST(TreeNode root) { if(root == null) { return true; } if(!isValidBST(root.left)) { return false; } long val = root.val; if(val <= previousNodeVal) { return false; } previousNodeVal = val; return isValidBST(root.right); } }
遞迴的分支優化:
當一個方法中有很多檢查語句,不通過返回false的話,那麼我們可以將整個方法預設返回false,只用聚焦在返回為true的情況,這樣會讓程式碼更清晰。
class Solution {
double last = -Double.MAX_VALUE;
public boolean isValidBST(TreeNode root) {
if (root == null) {
return true;
}
if (isValidBST(root.left)) {
if (last < root.val) {
last = root.val;
return isValidBST(root.right);
}
}
return false;
}
}
1.3.2. 判斷是否為完全二叉樹
廣度優先(層序遍歷):
public static boolean isCBT(TreeNode<Integer> root) {
if (root == null) return true;
Queue<TreeNode<Integer>> queue = new LinkedList<>();
TreeNode<Integer> node = root;
queue.add(node);
boolean isChildAllowed = true;
while (!queue.isEmpty()) {
node = queue.remove();
if (node.left != null) {
if (!isChildAllowed) return false;
queue.add(node.left);
} else {
isChildAllowed = false;
}
if (node.right != null) {
if (!isChildAllowed) return false;
queue.add(node.right);
} else {
isChildAllowed = false;
}
}
return true;
}
深度優先:
class Solution {
private int count = 0;
private int maxNum = 0;
public boolean isCompleteTree(TreeNode root) {
if(root == null) {
return true;
}
dfs(root, 1);
return count == maxNum;
}
private void dfs(TreeNode head, int num) {
count++;
maxNum = Math.max(maxNum, num);
if(head.left != null) {
dfs(head.left, num * 2);
}
if(head.right != null) {
dfs(head.right, num * 2 + 1);
}
}