1. 程式人生 > >小橙書閱讀指南(十)——二叉查找樹

小橙書閱讀指南(十)——二叉查找樹

lse 靈活性 鍵值對 理解 查找 技術 new pub ear

算法描述:二叉查找樹時一種能夠將鏈表插入的靈活性和有序數組查找的高效性結合起來的符號表(SymbolTable)實現。具體來說,就是使用每個節點含有兩個鏈接的二叉樹來高效地實現符號表。一顆二叉查找樹時一顆二叉樹,其中每個節點都含有一個Comparable的鍵且每個節點的鍵都大於其左子樹中的任意節點的鍵而小於右子樹的任意節點的鍵。

一、查找

一般來說,在符號表中查找一個鍵只可能出現命中和未命中兩種情況。一般通過遞歸算法在二叉樹中查找,如果樹時空的則查找未命中;如果被查找的鍵和根節點相等,查找命中,否則就在適當的子樹中繼續查找。

技術分享圖片

代碼示例:

    /**
     * 根據給定鍵獲取值
     *
     * 
@param key * @return */ public Value get(Key key) { return get(root, key); } private Value get(Node root, Key key) { if (root == null) { return null; } int cmp = key.compareTo(root.key); if (cmp < 0) { return get(root.left, key); }
if (cmp > 0) { return get(root.right, key); } return root.val; }

二、插入

插入的特性和查找難度差不多。當查找一個不存在於樹中的節點並結束於一條空鏈接時,我們需要做的就是將空鏈接指向一個含有被查找的鍵的新節點。如果查找不為空則該表當前節點的值。插入新的節點後需要沿搜索路徑向上更新鏈接並增加節點計數器的值。

技術分享圖片

代碼示例:

    /**
     * 插入鍵值對
     *
     * @param key
     * @param val
     */
    public
void put(Key key, Value val) { root = put(root, key, val); } /** * 插入操作調用的內部方法 * * @param root * @param key * @param val * @return */ private Node put(Node root, Key key, Value val) { // 如果是空節點則創建一個節點 if (root == null) { return new Node(key, val, 1); } // 如果節點非空則遞歸判斷 int cmp = key.compareTo(root.key); if (cmp < 0) { root.left = put(root.left, key, val); } else if (cmp > 0) { root.right = put(root.right, key, val); } else { root.val = val; } root.size = size(root.left) + size(root.right) + 1; return root; }

三、遍歷

二叉查找樹的遍歷通常使用中序遍歷,中序遍歷的順序是:先遍歷左子樹,再遍歷根節點,最後遍歷右節點。

代碼示例:

    /**
     * 中序遍歷方法
     *
     * @return
     */
    public List<Key> inOrder() {
        List<Key> keyList = new ArrayList<>();
        inOrder(root, keyList);
        return keyList;
    }

    private void inOrder(Node root, List<Key> keyList) {
        if (root != null) {
            inOrder(root.left, keyList);
            keyList.add(root.key);
            inOrder(root.right, keyList);
        }
    }

算法總結:查找二叉樹是一個補充結構,理解起來相對簡單。BST是紅黑樹的基礎。

相關鏈接:

Algorithms for Java

Algorithms for Qt

小橙書閱讀指南(十)——二叉查找樹