标签:
二叉排序树(Binary Sort Tree)又称二叉查找树(Binary Search Tree),亦称二叉搜索树。
图from baike
步骤:
若根结点的关键字值等于查找的关键字,成功。
否则,若小于根结点的关键字值,递归查左子树。
若大于根结点的关键字值,递归查右子树。
若子树为空,查找不成功。
平均情况分析(在成功查找两种的情况下):
在一般情况下,设 P(n,i)为它的左子树的结点个数为 i 时的平均查找长度。如图的结点个数为 n = 6 且 i = 3; 则 P(n,i)= P(6, 3) = [ 1+ ( P(3) + 1) * 3 + ( P(2) + 1) * 2 ] / 6= [ 1+ ( 5/3 + 1) * 3 + ( 3/2 + 1) * 2 ] / 6
注意:这里 P(3)、P(2) 是具有 3 个结点、2 个结点的二叉分类树的平均查找长度。 在一般情况,P(i)为具有 i 个结点二叉分类树的平均查找长度。
P(3) = (1+2+2)/ 3 = 5/3
P(2) = (1+2)/ 2 = 3/2∴ P(n,i)= [ 1+ ( P(i) + 1) * i + ( P(n-i-1) + 1) * (n-i-1) ] / n
∴ P(n)= P(n,i)/ n <= 2(1+I/n)lnn
因为 2(1+I/n)lnn≈1.38logn 故P(n)=O(logn)
以下是基于Java语言的实现与测试:
package com.wxisme.binarysearchtree; import java.util.Scanner; /** * 二叉查找(排序)树的实现 * @time 2015/8/16 12:02 * @author wxisme * @param <T> */ public class BinarySearchTree<T extends Comparable> { private class TreeNode { private T data; private TreeNode left; private TreeNode right; private TreeNode parent; public TreeNode() {} public TreeNode(T data) { this.data = data; this.left = null; this.right = null; this.parent = null; } } private TreeNode root; private int nodeCount; private int depth; public BinarySearchTree() {} public BinarySearchTree(T data) { root = new TreeNode(data); } /** * 添加元素 * @param data */ public void add(T data) { TreeNode node = new TreeNode(data); if(root == null) { root = node; } else { addSearch(node, root); } nodeCount ++; } public void addSearch(TreeNode node, TreeNode root) { if(node.data.compareTo(root.data)<=0) { if(root.left == null) { root.left = node; node.parent = root; return; } else { addSearch(node, root.left); } } else { if(root.right == null) { root.right = node; node.parent = root; return; } else { addSearch(node, root.right); } } } /** * 查找节点 * @param data * @return */ public TreeNode search(T data) { TreeNode it = root; if(it == null) { System.out.println("树为空!"); return null; } else { while(it != null) { if(data.compareTo(it.data)<0) { it = it.left; } else if(data.compareTo(it.data)>0) { it =it.right; } else { return it; } } } return null; } /** * 删除元素 * @param data */ public void remove(T data) { TreeNode node = search(data); if(node == null) { System.out.println("不存在此节点!"); return ; } //左右子树均为空 if(node.left==null && node.right==null) { if(root == node) { root = null; } else { if(node == node.parent.left) { node.parent.left = null; } else { node.parent.right = null; } node.parent = null; } } //左子树不为空,右子树为空 else if(node.left!=null && node.right==null) { if(root == node) { root = node.left; root.parent = null; } else { if(node == node.parent.left) { node.parent.left = node.left; node.left.parent = node.parent; node.left = null; node.parent = null; } else { node.parent.right = node.left; node.left.parent = node.parent; node.left = null; node.parent = null; } } } //右子树不为空,左子树为空 else if(node.left==null && node.right!=null) { if(root == node) { root = node.right; root.parent = null; } else { if(node == node.parent.left) { node.parent.left = node.right; node.right.parent = node.parent; node.right = null; node.parent = null; } else { node.parent.right = node.right; node.right.parent = node.parent; node.right = null; node.parent = null; } } } //左右子树均不为空 else { //左子树中值最大的节点 TreeNode leftMaxNode = node.left; while(leftMaxNode.right != null) { leftMaxNode = leftMaxNode.right; } //将左子树中值最大的节点移到要删除的节点的位置上来。 leftMaxNode.parent.right = null; leftMaxNode.parent = node.parent; if(node == node.parent.left) { node.parent.left = leftMaxNode; } else { node.parent.right = leftMaxNode; } leftMaxNode.left = node.left; leftMaxNode.right = node.right; //释放要删除的节点的引用 node.parent = node.left = node.right = null; } nodeCount --; } /** * 节点的个数 * @return */ public int size() { return nodeCount; } /** * 销毁树 */ public void destroy() { root = null; nodeCount = 0; } /** * 中序遍历树 */ public void traversal() { System.out.print("中序遍历:"); inOrderTraversal(root); System.out.println(); } public void inOrderTraversal(TreeNode root) { if(root == null) { return ; } inOrderTraversal(root.left); System.out.print(root.data); inOrderTraversal(root.right); } /** * 测试 * @param args */ public static void main(String[] args) { BinarySearchTree<Integer> tree = new BinarySearchTree<Integer>(); Scanner scan = new Scanner(System.in); for(int i=0; i<10; i++) { tree.add(scan.nextInt()); } tree.traversal(); System.out.print("删除节点:"); tree.remove(scan.nextInt()); tree.traversal(); System.out.println("节点的个数:" + tree.size()); System.out.println("销毁树"); tree.destroy(); System.out.println("节点的个数:" + tree.size()); } }
测试结果:
5 9 6 3 2 8 7 4 1 0
中序遍历:0123456789
删除节点:7
中序遍历:012345689
节点的个数:9
销毁树
节点的个数:0
标签:
原文地址:http://www.cnblogs.com/wxisme/p/4734011.html