二叉查找树

来源:互联网 发布:wps2016数据分析在哪里 编辑:程序博客网 时间:2024/06/08 04:43

具有以下特征的可以被定义为二叉查找树(Binary Search Tree)

(1)若左子树不空,则左子树上所有结点的值均小于它的根节点的值;

(2)若右子树不空,则右子树上所有结点的值均大于或等于它的根结点的值;

(3)中序遍历可以让节点有序


二叉查找树适用于范围查找,这个才是我们使用二叉树的最终目的,既然是范围查找,我们就知道了一个”min“和”max“,其实实现起来也很简单,

第一步:我们要在树中找到min元素,当然min元素可能不存在,但是我们可以找到min的上界,耗费时间为O(logn)。

第二步:从min开始我们中序遍历寻找max的下界。耗费时间为m。m也就是匹配到的个数。


二叉查找树的插入:

1.先执行查找,找到要插入元素位置的父节点

2.判断其是父节点的左叶子/右叶子,被插入节点做为叶子节点插入

二叉查找树的删除:

1.根据给定的key值找到要被删除的节点p,判断是否是叶子节点(是则直接删除)

2.判断其是否有左孩子,如果有则找到左孩子的最右节点r,将r的(key,value)数据覆盖p的(key,value)数据,没有则直接使用右孩子覆盖p

3.判断r是否等于p的左孩子节点,是则将p的左孩子指向r的左孩子,不是则将r的父节点的右孩子指向r(左儿子的最右节点)的左孩子

下面是一个查找二叉树的实现:

package test;import java.util.Random;public class BinaryTreeTest {private static class BinaryNode implements Comparable<BinaryNode> {// 节点private String key;// 数量private int total;// 左子节点private BinaryNode leftNode;// 右子节点private BinaryNode rightNode;// 父节点private BinaryNode parentNode;public BinaryNode getParentNode() {return parentNode;}public void setParentNode(BinaryNode parentNode) {this.parentNode = parentNode;}public BinaryNode getLeftNode() {return leftNode;}public void setLeftNode(BinaryNode leftNode) {leftNode.setParentNode(this);this.leftNode = leftNode;}public BinaryNode getRightNode() {return rightNode;}public void setRightNode(BinaryNode rightNode) {rightNode.setParentNode(this);this.rightNode = rightNode;}public BinaryNode(String key) {this.key = key;total = 1;}public int compareTo(BinaryNode o) {int result = (o.getKey()).compareTo(key);if(result == 0){return 0;}else if(result < 0){return -1;}else if(result > 0){return 1;}return 0;}public int compareTo(String k) {int result = k.compareTo(key);if(result == 0){return 0;}else if(result > 0){return -1;}else if(result < 0){return 1;}return 0;}public void increament() {total++;}public String getKey() {return this.key;}public void setKey(String key) {this.key = key;}}public static void addChildNode(BinaryNode startNode,BinaryNode addNode){int compare = addNode.compareTo(startNode);switch (compare) {//相等,则当前节点数量+1case 0:startNode.increament();break;//大于则找到其右子节点,并继续执行添加过程case 1:BinaryNode rightNode = startNode.getRightNode();if(rightNode == null){startNode.setRightNode(addNode);}else{addChildNode(rightNode, addNode);}break;//小于则找到其左子节点继续执行添加过程case -1:BinaryNode leftNode = startNode.getLeftNode();if(leftNode == null){startNode.setLeftNode(addNode);}else{addChildNode(leftNode, addNode);}break;default:break;}}public static BinaryNode sercherChildNode(BinaryNode startNode,String sercherKey){int compare = startNode.compareTo(sercherKey);switch (compare) {//相等,则当前节点数量+1case 0:return startNode;//大于则找到其右子节点,并继续执行添加过程case 1:return sercherChildNode(startNode.getRightNode(), sercherKey);//小于则找到其左子节点继续执行添加过程case -1:return sercherChildNode(startNode.getLeftNode(), sercherKey);}return null;}/** * 1.若p有左子树,找到其左子树的最右边的结点r,用该结点r来替代p,把r的左孩子 *作为r的父亲的右孩子。 *2.若p没有左子树,直接用p的右孩子取代它。 */public static BinaryNode deleteChildNode(BinaryNode startNode,String key){BinaryNode node = sercherChildNode(startNode, key);if(node != null){BinaryNode left = node.getLeftNode();if(left != null){//查找最右的节点BinaryNode pre = left;while(pre.getRightNode()!=null){pre = pre.getRightNode();}node.setKey(pre.getKey());//如果pre是node的左子树,则把node的左子树设置成pre的左子树if(pre.compareTo(left) == 0){node.setLeftNode(pre.getLeftNode());}else{//把pre节点的父节点的右子树 设置成pre的左子树pre.getParentNode().setRightNode(pre.getLeftNode());}}else{//左子树为空,则直接设置node为右子树node = node.getRightNode();}}return null;}//随机生成一个1-10长度的字符串public static String genStr() {StringBuffer buffer = new StringBuffer("");Random random = new Random();int strLength = random.nextInt(10);strLength = strLength==0?1:strLength;for(int i =0;i<strLength;i++){char r = (char)(random.nextInt(82)+40);buffer.append(r);}return buffer.toString();}}






0 0