Java实现二叉搜索树
2015-11-23 17:20
465 查看
前言
在做算法导论第12章的习题时,有一些习题需要用到二叉搜索树的数据结构,为了方便,我将其用Java实现了这个数据结构。Talk is cheap,show me the code.我就闲话少说了,代码如下。
Java代码实现二叉搜索树数据结构
package hanxl.insist.twelvechapter; import java.util.Stack; /** * 搜索二叉树 */ public class BinarySearchTree { private TreeNode root; /** * 将数组构建成一个二叉搜索树 * @param arr */ public BinarySearchTree(int[] arr) { for (int i : arr) insert(i); } /** * 将给定的元素插入树中 * @param e */ public void insert(Integer e) { TreeNode insertPosition = root; TreeNode insertPositionParent = null; //记录待插入位置的父节点 while ( insertPosition != null ) { insertPositionParent = insertPosition; if ( e < insertPosition.item ) insertPosition = insertPosition.left; else insertPosition = insertPosition.right; } TreeNode insertPoint = new TreeNode(null, e, null, insertPositionParent); if ( insertPositionParent == null ) //树是空的情况 root = insertPoint; else if ( e < insertPositionParent.item ) insertPositionParent.left = insertPoint; else insertPositionParent.right = insertPoint; } /** * 将给定的元素从树中删除 */ public void delete(Integer num) { TreeNode delNode = search(root, num); if ( delNode.right == null ) transplant(delNode, delNode.left); else if ( delNode.left == null ) transplant(delNode, delNode.right); else { //无论minimum是不是delNode的右孩子,minimum都会与delNode交换 //只不过在不是的这种情况下,minimum首先要与自己的右孩子进行交换,然后在重新定义minimum的右孩子 TreeNode minimum = minimum(delNode.right); if(minimum.p != delNode) { transplant(minimum, minimum.right); minimum.right = delNode.right; minimum.right.p = minimum; } transplant(delNode, minimum); minimum.left = delNode.left; minimum.left.p = minimum; } } /** * 用一颗以tmpNode为根的子树来替换一棵以delNode为根的子树 * 结点delNode的父亲就变为tmpNode的父亲,并且最后tmpNode * 成为delNode的父亲的相应孩子。 */ private void transplant(TreeNode delNode, TreeNode tmpNode) { if(delNode.p == null) root = tmpNode; if(delNode == delNode.p.left) delNode.p.left = tmpNode; else delNode.p.right = tmpNode; if(tmpNode != null) tmpNode.p = delNode.p; } /** * 在给定的节点及其后代中查询key * @return 如果查询到关键字则返回它,否则返回Null */ public TreeNode search(TreeNode node, Integer key) { if ( node == null || node.item == key ) return node; else if ( node.item < key ) return search(node.right, key); else return search(node.left, key); } /** * 获取给定节点的前驱 */ public TreeNode predecessor(TreeNode node) { //如果节点有左孩子,它的前驱一定为左子树中的最大值 if (node.left != null) return maximum(node.left); TreeNode parent = node.p; // 如果节点是其父亲的左孩子,那么其前驱一定是遇到的第一个节点是其父亲的右孩子 while (parent != null && node == parent.left) { node = parent; parent = parent.p; } //如果节点是其父亲的右孩子,它的前驱一定是它的父亲 return parent; } /** * 获取给定节点的后继 */ public TreeNode successor(TreeNode node) { if (node.right != null) return minimum(node.right); TreeNode parent = node.p; while (parent != null && node == parent.right) { node = parent; parent = parent.p; } return parent; } /** * 获取给定节点及其子树中的最小值 * @return */ public TreeNode minimum(TreeNode node) { TreeNode minimum = node; while ( minimum.left != null ) minimum = minimum.left; return minimum; } /** * 获取给定节点及其子树中的最大值 * @return */ public TreeNode maximum(TreeNode node) { TreeNode maximum = node; while ( maximum.right != null ) maximum = maximum.right; return maximum; } /** * 非递归版本的中序遍历 */ public void inorderTreeWalk() { Stack<TreeNode> stack = new Stack<TreeNode>(); //这里我用Java.util包中自带的栈 loadLeftNode(root, stack); System.out.print("中序遍历的结果: "); while ( !stack.isEmpty() ) { TreeNode currentNode = stack.pop(); System.out.print(currentNode.item + " "); currentNode = currentNode.right; loadLeftNode(currentNode, stack); } System.out.println(); } /** * 加载给定节点的所有后代中的左节点到栈中,直到叶子 * 节点为止 * @param stack */ private void loadLeftNode(TreeNode node, Stack<TreeNode> stack) { TreeNode temp = node; while ( temp != null ) { stack.push(temp); temp = temp.left; } } public static class TreeNode { Integer item; TreeNode left; TreeNode right; TreeNode p; TreeNode(TreeNode left, Integer element, TreeNode right, TreeNode p) { this.item = element; this.left = left; this.right = right; this.p = p; } } public TreeNode getRoot() { return root; } }
测试数据结构的代码
public static void main(String[] args) { int[] a = { 23, 45, 12, 56, 32, 78, 100, 3, 90, 678, 2, 4, 8, 92, 67, 49 }; BinarySearchTree tree = new BinarySearchTree(a); tree.inorderTreeWalk(); //中序遍历树 System.out.println(tree.search(tree.getRoot(), 12)); //在树中查找给定的关键字 System.out.println("树中的最小值为:" + tree.minimum(tree.getRoot()).item); System.out.println("树中的最大值为:" + tree.maximum(tree.getRoot()).item); System.out.println("树根为:" + tree.getRoot().item + " 树根的前驱为:" + tree.predecessor(tree.getRoot()).item); System.out.println("树根为:" + tree.getRoot().item + " 树根的后继为:" + tree.successor(tree.getRoot()).item); tree.delete(100); tree.inorderTreeWalk(); //中序遍历树 }
相关文章推荐
- Lua教程(七):数据结构详解
- 解析从源码分析常见的基于Array的数据结构动态扩容机制的详解
- C#数据结构揭秘一
- 数据结构之Treap详解
- JavaScript数据结构和算法之图和图算法
- Java数据结构及算法实例:冒泡排序 Bubble Sort
- Java数据结构及算法实例:插入排序 Insertion Sort
- Java数据结构及算法实例:考拉兹猜想 Collatz Conjecture
- java数据结构之java实现栈
- java数据结构之实现双向链表的示例
- Java数据结构及算法实例:选择排序 Selection Sort
- Java数据结构及算法实例:朴素字符匹配 Brute Force
- Java数据结构及算法实例:汉诺塔问题 Hanoi
- Java数据结构及算法实例:快速计算二进制数中1的个数(Fast Bit Counting)
- java数据结构和算法学习之汉诺塔示例
- Java数据结构及算法实例:三角数字
- Java数据结构之简单链表的定义与实现方法示例
- 数据结构之AVL树详解
- qqwry.dat的数据结构图文解释第1/2页
- JavaScript中数据结构与算法(五):经典KMP算法