
https://labuladong.online/algo/data-structure-basic/tree-map-basic/
今天是學習的第 26 天,主要學習了二叉搜索樹的應用:
二叉搜索樹(BST)的特點是「左小右大」:
對於每一個節點,其左子樹的每個節點的值都要小於這個節點的值,右子樹的每個節點都要大於這個節點的值。
下面的這棵樹就是一棵 BST:

我們可以利用這個左小右大的特性,快速在 BST 中找到某個節點,這就是 BST 的優勢。
在二叉樹中搜索指定節點:
// 在二叉樹中搜索指定節點:
let targetNode = null;
function traverse(root, targetVal) {
    console.log(root);
    if (root === null) {
        return;
    }
    if (root.val === targetVal) {
        // 找到目標節點
        targetNode = root;
    }
    if (targetNode !== null) {
        // 已經找到目標,結束遍歷
        return;
    }
    // 二叉樹遍歷框架
    traverse(root.left, targetVal);
    traverse(root.right, targetVal);
}
// 建立一棵 BST
//        7
//      /   \
//     4     9
//    / \     \
//   1   5    10
var root = new TreeNode(7);
root.left = new TreeNode(4);
root.right = new TreeNode(9);
root.left.left = new TreeNode(1);
root.left.right = new TreeNode(5);
root.right.right = new TreeNode(10);
traverse(root, 10);
// 需要遍歷 11 次才找到目標節點 10
// TreeNode {val: 7, left: TreeNode, right: TreeNode}
// TreeNode {val: 4, left: TreeNode, right: TreeNode}
// TreeNode {val: 1, left: TreeNode, right: TreeNode}
// TreeNode null
// TreeNode null
// TreeNode {val: 5, left: TreeNode, right: TreeNode}
// TreeNode null
// TreeNode null
// TreeNode {val: 9, left: TreeNode, right: TreeNode}
// TreeNode null
// TreeNode {val: 10, left: TreeNode, right: TreeNode}
利用 BST 的特性搜索指定節點:
// 利用 BST 的特性搜索指定元素
let targetNode = null;
function traverse(root, targetVal) {
    console.log(root);
    if (root === null) {
        return;
    }
    if (root.val === targetVal) {
        targetNode = root;
    }
    if (targetNode !== null) {
        // 已經找到目標,不需要繼續遍歷了
        return;
    }
    // 根據 targetVal 和當前節點的大小
    // 可以判斷應該去左子樹還是右子樹進行搜索
    if (root.val < targetVal) {
        traverse(root.right, targetVal);
    } else {
        traverse(root.left, targetVal);
    }
}
// 建立一棵 BST
//        7
//      /   \
//     4     9
//    / \     \
//   1   5    10
var root = new TreeNode(7);
root.left = new TreeNode(4);
root.right = new TreeNode(9);
root.left.left = new TreeNode(1);
root.left.right = new TreeNode(5);
root.right.right = new TreeNode(10);
traverse(root, 10);
// 只需要遍歷 3 次就能找到目標節點 10
// TreeNode {val: 7, left: TreeNode, right: TreeNode}
// TreeNode {val: 9, left: null, right: TreeNode}
// TreeNode {val: 10, left: null, right: null}
利用 BST 左小右大的特性,理想的時間複雜度是樹的高度 O(log n),而普通的二叉樹遍歷則需要 O(n) 的時間複雜度。