java 實現二叉搜尋樹
阿新 • • 發佈:2018-12-17
實現程式碼如下:
/** * Java 語言: 二叉查詢樹 * * @author skywang * @date 2013/11/07 */ @SuppressWarnings("unused") public class BSTree<T extends Comparable<T>> { private BSTNode<T> mRoot; // 根結點 public class BSTNode<T extends Comparable<T>> { T key; // 關鍵字(鍵值) BSTNode<T> left; // 左孩子 BSTNode<T> right; // 右孩子 BSTNode<T> parent; // 父結點 public BSTNode(T key, BSTNode<T> parent, BSTNode<T> left, BSTNode<T> right) { this.key = key; this.parent = parent; this.left = left; this.right = right; } public T getKey() { return key; } public String toString() { return "key:" + key; } } public BSTree() { mRoot = null; } /* * 前序遍歷"二叉樹" */ private void preOrder(BSTNode<T> tree) { if (tree != null) { System.out.print(tree.key + " "); preOrder(tree.left); preOrder(tree.right); } } public void preOrder() { preOrder(mRoot); } /* * 中序遍歷"二叉樹" */ private void inOrder(BSTNode<T> tree) { if (tree != null) { inOrder(tree.left); System.out.print(tree.key + " "); inOrder(tree.right); } } public void inOrder() { inOrder(mRoot); } /* * 後序遍歷"二叉樹" */ private void postOrder(BSTNode<T> tree) { if (tree != null) { postOrder(tree.left); postOrder(tree.right); System.out.print(tree.key + " "); } } public void postOrder() { postOrder(mRoot); } /* * (遞迴實現)查詢"二叉樹x"中鍵值為key的節點 */ private BSTNode<T> search(BSTNode<T> x, T key) { if (x == null) return null; int cmp = key.compareTo(x.key); if (cmp < 0) return search(x.left, key); else if (cmp > 0) return search(x.right, key); else return x; } public BSTNode<T> search(T key) { return search(mRoot, key); } /* * (非遞迴實現)查詢"二叉樹x"中鍵值為key的節點 */ private BSTNode<T> iterativeSearch(BSTNode<T> x, T key) { while (x != null) { int cmp = key.compareTo(x.key); if (cmp < 0) x = x.left; else if (cmp > 0) x = x.right; else return x; } return null; } public BSTNode<T> iterativeSearch(T key) { return iterativeSearch(mRoot, key); } /* * 查詢最小結點:返回tree為根結點的二叉樹的最小結點。 */ private BSTNode<T> minimum(BSTNode<T> tree) { if (tree == null) return null; while (tree.left != null) tree = tree.left; return tree; } public T minimum() { BSTNode<T> p = minimum(mRoot); if (p != null) return p.key; return null; } /* * 查詢最大結點:返回tree為根結點的二叉樹的最大結點。 */ private BSTNode<T> maximum(BSTNode<T> tree) { if (tree == null) return null; while (tree.right != null) tree = tree.right; return tree; } public T maximum() { BSTNode<T> p = maximum(mRoot); if (p != null) return p.key; return null; } /* * 找結點(x)的後繼結點。即,查詢"二叉樹中資料值大於該結點"的"最小結點"。 */ public BSTNode<T> successor(BSTNode<T> x) { // 如果x存在右孩子,則"x的後繼結點"為 "以其右孩子為根的子樹的最小結點"。 if (x.right != null) return minimum(x.right); // 如果x沒有右孩子。則x有以下兩種可能: // (01) x是"一個左孩子",則"x的後繼結點"為 "它的父結點"。 // (02) x是"一個右孩子",則查詢"x的最低的父結點,並且該父結點要具有左孩子",找到的這個"最低的父結點"就是"x的後繼結點"。 BSTNode<T> y = x.parent; while ((y != null) && (x == y.right)) { x = y; y = y.parent; } return y; } /* * 找結點(x)的前驅結點。即,查詢"二叉樹中資料值小於該結點"的"最大結點"。 */ public BSTNode<T> predecessor(BSTNode<T> x) { // 如果x存在左孩子,則"x的前驅結點"為 "以其左孩子為根的子樹的最大結點"。 if (x.left != null) return maximum(x.left); // 如果x沒有左孩子。則x有以下兩種可能: // (01) x是"一個右孩子",則"x的前驅結點"為 "它的父結點"。 // (01) x是"一個左孩子",則查詢"x的最低的父結點,並且該父結點要具有右孩子",找到的這個"最低的父結點"就是"x的前驅結點"。 BSTNode<T> y = x.parent; while ((y != null) && (x == y.left)) { x = y; y = y.parent; } return y; } /* * 將結點插入到二叉樹中 * * 引數說明: * tree 二叉樹的 * z 插入的結點 */ private void insert(BSTree<T> bst, BSTNode<T> z) { int cmp; BSTNode<T> y = null; BSTNode<T> x = bst.mRoot; // 查詢z的插入位置 while (x != null) { y = x; cmp = z.key.compareTo(x.key); if (cmp < 0) x = x.left; else x = x.right; } z.parent = y; if (y == null) bst.mRoot = z; else { cmp = z.key.compareTo(y.key); if (cmp < 0) y.left = z; else y.right = z; } } /* * 新建結點(key),並將其插入到二叉樹中 * * 引數說明: * tree 二叉樹的根結點 * key 插入結點的鍵值 */ public void insert(T key) { BSTNode<T> z = new BSTNode<>(key, null, null, null); // 如果新建結點失敗,則返回。 if (z != null) insert(this, z); } /* * 刪除結點(z),並返回被刪除的結點 * * 引數說明: * bst 二叉樹 * z 刪除的結點 */ private BSTNode<T> remove(BSTree<T> bst, BSTNode<T> z) { BSTNode<T> x = null; BSTNode<T> y = null; if ((z.left == null) || (z.right == null)) y = z; else y = successor(z); if (y.left != null) x = y.left; else x = y.right; if (x != null) x.parent = y.parent; if (y.parent == null) bst.mRoot = x; else if (y == y.parent.left) y.parent.left = x; else y.parent.right = x; if (y != z) z.key = y.key; return y; } /* * 刪除結點(z),並返回被刪除的結點 * * 引數說明: * tree 二叉樹的根結點 * z 刪除的結點 */ public void remove(T key) { BSTNode<T> z, node; if ((z = search(mRoot, key)) != null) if ((node = remove(this, z)) != null) node = null; } /* * 銷燬二叉樹 */ private void destroy(BSTNode<T> tree) { if (tree == null) return; if (tree.left != null) destroy(tree.left); if (tree.right != null) destroy(tree.right); tree = null; } public void clear() { destroy(mRoot); mRoot = null; } /* * 列印"二叉查詢樹" * * key -- 節點的鍵值 * direction -- 0,表示該節點是根節點; * -1,表示該節點是它的父結點的左孩子; * 1,表示該節點是它的父結點的右孩子。 */ private void print(BSTNode<T> tree, T key, int direction) { if (tree != null) { if (direction == 0) // tree是根節點 System.out.printf("%2d is root\n", tree.key); else // tree是分支節點 System.out.printf("%2d is %2d's %6s child\n", tree.key, key, direction == 1 ? "right" : "left"); print(tree.left, tree.key, -1); print(tree.right, tree.key, 1); } } public void print() { if (mRoot != null) print(mRoot, mRoot.key, 0); } }
原文連結: