算法描述:二叉查找樹時一種可以將鏈表插入的靈活性和有序數組查找的高效性結合起來的符號表(SymbolTable)實現。具體來講,就是使用每一個節點含有兩個連接的二叉樹來高效地實現符號表。一顆二叉查找樹時一顆二叉樹,其中每一個節點都含有一個Comparable的鍵且每一個節點的鍵都大於其左子樹中的任意節點的鍵而小於右子樹的任意節點的鍵。git
1、查找算法
通常來講,在符號表中查找一個鍵只可能出現命中和未命中兩種狀況。通常經過遞歸算法在二叉樹中查找,若是樹時空的則查找未命中;若是被查找的鍵和根節點相等,查找命中,不然就在適當的子樹中繼續查找。數組
代碼示例:spa
/** * 根據給定鍵獲取值 * * @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; }
2、插入3d
插入的特性和查找難度差很少。當查找一個不存在於樹中的節點並結束於一條空連接時,咱們須要作的就是將空連接指向一個含有被查找的鍵的新節點。若是查找不爲空則該表當前節點的值。插入新的節點後須要沿搜索路徑向上更新連接並增長節點計數器的值。code
代碼示例:blog
/** * 插入鍵值對 * * @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; }
3、遍歷遞歸
二叉查找樹的遍歷一般使用中序遍歷,中序遍歷的順序是:先遍歷左子樹,再遍歷根節點,最後遍歷右節點。get
代碼示例:it
/** * 中序遍歷方法 * * @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是紅黑樹的基礎。
相關連接: