二叉查找树 Java实现

来源:互联网 发布:网络有关的电影 编辑:程序博客网 时间:2024/05/22 20:23

二叉查找树是一棵二叉树,特别之处在于:对于树中的每个节点X,它的左子树中所有项的值小于X中的项,而它的右子树中所有项的值大于X中的项。

如果插入序列是随机的,则平均深度是O(logN)。

如果插入序列是预先排好序的,那么会退化成链表。

一种解决方案是有一个附加平衡条件,如AVL树,红黑树(red black tree);

另一种是每次操作之后使用一个规则调整平衡,如伸展树(splay tree)。

/** * 二叉查找树 *  * 操作的平均时间为O(logN) *  * 公有方法:  * void insert(T x);  * void remove(T x);  * T findMin(); * T findMax(); * boolean contains(T x);  * void makeEmpty(); * boolean isEmpty(); * void printTree(); */public class BinarySearchTree<T extends Comparable<? super T>> {private BinaryNode<T> root; // 唯一数据域是对树根的引用// 节点类private static class BinaryNode<T> {private T element;private BinaryNode<T> left;private BinaryNode<T> right;BinaryNode(T theElement, BinaryNode<T> lt, BinaryNode<T> rt) {element = theElement;left = lt;right = rt;}}// 构造器public BinarySearchTree() {root = null;}// 插入,调用更general的私有插入方法public void insert(T x) {root = insert(x, root);}// 删除,调用更general的remove方法public void remove(T x) {root = remove(x, root);}// 最小项,为空返回nullpublic T findMin() {if (isEmpty())return null;return findMin(root).element;}// 最大项,为空返回nullpublic T findMax() {if (isEmpty())return null;return findMax(root).element;}// containspublic boolean contains(T x) {return contains(x, root);}//public void makeEmpty() {root = null;}//public boolean isEmpty() {return root == null;}//public void printTree() {if (isEmpty()) {System.out.println("Empty tree");return;} elseprintTree(root);}private BinaryNode<T> insert(T x, BinaryNode<T> t) {// 如果根为空if (t == null)return new BinaryNode<>(x, null, null);int compareResult = x.compareTo(t.element);// 这里只有小于和大于,如果等于,则不管if (compareResult < 0)t.left = insert(x, t.left);else if (compareResult > 0)t.right = insert(x, t.right);return t;}private BinaryNode<T> remove(T x, BinaryNode<T> t) {if (t == null)return t; // Item not found; do nothingint compareResult = x.compareTo(t.element);if (compareResult < 0)t.left = remove(x, t.left);else if (compareResult > 0)t.right = remove(x, t.right);// 有两个孩子,则把右子树最小节点值赋给当前节点,删除右子树最小节点// 注意这样的删除,会造成树的不平衡,// 如果随机的选择左子树的最大值或者右子树的最小值,可以避免删除造成的不平衡else if (t.left != null && t.right != null) {// 找到右子树最小节点,把值赋给当前节点t.element = findMin(t.right).element;// 删除右子树最小节点t.right = remove(t.element, t.right);} elset = (t.left != null) ? t.left : t.right;return t;}// 只要有左儿子,就向左进行,这里用递归方式编程private BinaryNode<T> findMin(BinaryNode<T> t) {if (t == null)return null;else if (t.left == null)return t;return findMin(t.left);}// 只要有右儿子,就向右进行,这里用while循环代替递归private BinaryNode<T> findMax(BinaryNode<T> t) {if (t != null)while (t.right != null)t = t.right;return t;}private boolean contains(T x, BinaryNode<T> t) {if (t == null)return false;int compareResult = x.compareTo(t.element);// 这里的递归调用可以用while循环代替if (compareResult < 0)return contains(x, t.left);else if (compareResult > 0)return contains(x, t.right);elsereturn true; // Match}// 中序遍历print,结果是从小到大输出private void printTree(BinaryNode<T> t) {if (t != null) {printTree(t.left);System.out.println(t.element);printTree(t.right);}}// 计算树高度,本程序没用到private int height(BinaryNode<T> t) {if (t == null)return -1;elsereturn 1 + Math.max(height(t.left), height(t.right));}// 测试public static void main(String[] args) {BinarySearchTree<Integer> t = new BinarySearchTree<>();for (int i = 0; i <= 100; i++) {t.insert(i);}t.printTree();System.out.println(t.findMax());System.out.println(t.findMin());System.out.println(t.contains(101));}}




原创粉丝点击