对于大量的数据的输入,我们采用另一种大部分操作时间为log的简单数据结构,同时,在这个情况下线性列表访问的时间太慢,不适合使用,这种简单的数据结构叫做二叉查找树,其是两种库集合类TreeSet和TreeMap实现的基础。
树的定义,一棵树有一个根节点和许多的子节点,每个子节点可能有一个或者是多个子节点,并且,没有儿子的节点成为叶节点。具有相同父节点的叫做兄弟,从某个节点n1到节点nk,称为路径。一般的某个节点的高为此节点到此节点下面的分支的最长路径,也就是说,叶节点的高度为0,而深度是指,一棵树的最深的树叶的深度,该深度总是等于这棵树的高。
树的实现:
一种方式为可以在每一个节点除外的还要有一条链,使得每一个子节点的儿子指向它,不过直接的建立其之间的链是比较浪费空间的,解决方案为将每个节点的所有儿子都放在树节点的链表中。
二叉树,即每个节点的子节点数不能多于2,因此我们可以直接保存链接到它们的链,树结构的声明类似于双链列表的声明。
对于二叉查找树,其特性为,左子树的值小于根节点,右子树的值大于根节点,对于二叉查找树来说其查找最大值最小值的效率是很高的,而删除操作,会破坏树的平衡,比如我们执行删除最小值的操作,就会失去平衡,并且删除操作的效率并不高。
//BinarySearchTree class // //CONSTRUCTION: with no initializer // //**********************public operations************** // void insert(x) --> Insert x // void remove(x) --> Remove x // boolean contains(x) --> Return true if x is present //Comparable findMin( ) --> Return smallest item //Comparable findMax( ) --> Return largest item //boolean isEmpty( ) --> Return true if empty;else false //void makeEmpty( ) --> Remove all items //void printTree( ) -->Print tree in sorted order //***********************ERRORS************************* // // Throws UnderflowException as approprate //Implements an unbalanced binary search tree, //Note that all 'matching' is based on the compare to method. //@author Zhang TiLing public class BinarySearchTree<AnyType extends Comparable<? super AnyType>> { // Construct the tree public BinarySearchTree() { root = null; } // Insert into the tree; duplicates are ignored. // @param x the item to insert. public void insert(AnyType x) { root = insert(x, root); } // Remove from the tree. Nothing is done if x is not found. // @param x is the item to remove. public void remove(AnyType x) { root = remove(x,root); } // Find the smallest item in the tree. // @return smallest item or null if empty public AnyType finMin() { if(isEmpty( )) throw new UnderflowException(); return findMin(root).element; } // Find the largest item in the tree. // @return the largest item of null of empty public AnyType findMax() { if(isEmpty()) throw new UnderflowException(); return findMax(root).element; } // Find an item in the tree. // @param x the item to search for. // @return true if not found. public boolean contains(AnyType x) { return contains(x, root); } // Make the tree logically empty public void makeEmpty() { root = null; } // Test if the tree is logically empty. // @return true if empty,false otherwise. public boolean isEmpty() { return root == null; } // Print the tree contains in sorted order public void printTree() { if(isEmpty()) throw new UnderflowException(); else printTree(root); } // Internal method to isnert into a subtree. // @param x the item to insert. // @parma t hte node that roots the subtree. // @return the new root of the subtree. private BinaryNode<AnyType> isnert (AnyType x,BinaryNode<AnyType> 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); else ; return t; } // Internal method to find the smallest item in a subtree. // @param t the node that roots the subtree. // @return node containing the smallest item. private BinaryNode<AnyType> findMin(BinaryNode<AnyType> t) { if(t == null) return null; else if (t.left == null) return t; return findMin(t.left); } // Internal method to find the largest item in a subtree. // @param t the node that roots the subtree. // @return node containing the largest item. private BinaryNode<AnyType> findMin(BinaryNode<AnyType> t) { if(t != null) while(t.right != null) t = t.right; return t; } // Internal method to find an item in a subtree. // @param x is item to search for. // @param t the node that roots the subtree. // @return node containing the matched item. private boolean contains(AnyType x,BinaryNode<AnyType> t) { if (t == null) return false; int compareResult = x.compareTo(t.element); if(compareResult < 0) return contains(x,t.left); else if (compareResult > 0) return contains(x,x.right); else return true; } // Internal method to print a subtree in sorted order. // @param t the node that roots the subtree. private void printTree(BinaryNode<AntType> t) { if(t != null) { printTree(t.left); System.out.println(t.element); printTree(t.right); } } // Internal method to compute height of a subtree. // @param t the node that roots the subtree. private int height(BinaryNode<AnyType> t) { if(t == null) return -1; else return 1 + Math.max(height(t.left),height(t.right)); } // Basic node sorted in unbalanceed binary search tree private static class BinaryNode<AnyType> { BinaryNode(AnyType theElement) { this(theElement,null,null); } BinaryNode(AnyType theElement,BinaryNode<AnyType> lt,BinaryNode<AnyType> rt) { element = theElement; left = lt; right = rt; } AnyType element; //The data in the node BinaryNode<AnyType> left; //Left child BinaryNode<AnyType> right;//Right child } private BinaryNode<AnyType> root; }