树 - (二叉查找树,红黑树,B树)-二叉查找树 BST

二叉查找树 BST

查找树是一种数据结构,支持动态集合操作。在二叉查找树上执行基本操作的时间与树的高度成正比。对已n个节点的完全二叉树,各种操作的最坏情况运行时间O(logn). 但是如果二叉查找树退化成含n个节点的线性链,各种操作的最坏情况运行时间O(n)。 一颗随机构造的二叉查找树的操作平均时间是O(logn).

性质:

对于任何节点x,其左子树的关键字最大不超过key[x],其右子树的关键字最小不小于key[x]. 因此可以使用中序遍历算法,输出有序的树的所有关键字。

不同的二叉查找树可以表示同一组值。

查找二叉查找树的时间可以在O(h) = O(logn)的时间内完成。

关于二叉树的一些数学性质:
1. 在二叉树的第i层上至多有2(i-1)个节点(i>=1)
2. 深度为k的二叉树至多有2k-1个节点
3. 对于任何一棵二叉树T,如果其叶子节点数为n0,度为2的节点数为n2,则n0=n2+1.

操作及代码

        // 返回指向包含关键字k的节点的指针
    public TreeNode search(TreeNode root, int k){
        if(root==null){
            return null;
        }
        if(root.val == k)
            return root;
        if(root.val > k){
            return search(root.left,k);
        }
        else
            return search(root.right,k);
    }

    //非递归 - 返回指向包含关键字k的节点的指针
    public TreeNode searchIterative(TreeNode root, int k){
        while(root!=null){
            if(root==null || root.val == k){
                return root;
                }
            if(root.val>k)
            {
                root = root.left;
            }
            else
                root = root.right;
            }
        return root;
    }
    // 返回最小值节点
    public TreeNode minimal(TreeNode root){
        if(root ==null){
            return null;
        }
        while(root.left!=null){
            root = root.left;
        }
        return root;
    }
    // 返回最大值节点
    public TreeNode maximal(TreeNode root){
        if(root ==null){
            return null;
        }
        while(root.right!=null){
            root = root.right;
        }
        return root;
    }

插入

插入:从根结点开始,沿树下降。指针 x 跟踪这条路径,而 y 始终指向 x 的父结点。根据 key[z] 与 key[x] 的比较结果,决定向左向右转。直到 x 成为 NIL 为止。这个 NIL 所占位置及我们想插入 z 的地方,y 即为 z 的父结点。

        // 插入
    public TreeNode insert (TreeNode root, TreeNode x){
        TreeNode p = root;
        TreeNode y = new TreeNode();
        if(p==null){
            root = x;
            return root;
        }
        while(p!=null)      
        {    
            if(p.val >= x.val){
                y = p;
                p = p.left;
            }
            else{
                y = p;
                p =p.right;
            }
        }
        // 树本来没有节点的时候
        x.parent = y;
        if(x.val <= y.val){
            y.left = x;
        }
        else{
            y.right = x;
        }
        return root;
    }


完整代码
package test;

/**
 * @author 作者 MarcoSpring:
 * @version 创建时间:2012-8-3 上午10:14:51 二叉搜索树
 */
public class Tree {
	public TreeNode root;// 根节点

	// 查找节点
	public TreeNode search(int Key) {
		TreeNode node = root;
		// 首先定义一个节点让其指向根,在下面的循环中
		// 只要节点值不等于要查找的节点值就进入循环如果没有找到则返回null
		while (node.keyValue != Key) {
			if (Key < node.keyValue) { // 如果要查找的值小于节点值则指向左节点
				node = node.leftNode;
			} else { // 否则指向右节点
				node = node.rightNode;
			}
			if (node == null) { // 如果节点为空了则返回null
				return null;
			}
		}
		return node;
	}

插入节点,递归方式
private TreeNode insert(x,TreeNode root){
		if(t==null)return new TreeNode(x,null,null);
		else if(x<root.data){
			root.left=insert(x,root.left);
		}
		else if(x<root.data){
			root.right=insert(x,root.right);
		}
		else ;
		return root;
	}


 
 

实际用途

搜索应用中使用,尤其是数据频繁插入和删除等等更改操作。比如setmap

虽然BST的操作用数组完全可以实现,但是数组只适合那种write once, read many times的操作。
然而当要进行操作诸如 插入,删除交换的时候,BST的性能远远超过了数组。BST 是 node based 数据结构,
而数组是 contiguous chunk of memory, 即基于连续内存的数据结构,插入,删除交换要BST更好。

举个例子
BST和哈希表有何区别? 存储手机上的通讯录用哪个数据结构好?
哈希表可以O(1)时间进行搜索插入
BST 可以O(nlogn)时间进行搜索插入。 在这一点BST稍慢。
但是二者最大的区别是哈希表是一个无序的DS,while, BSTs 是有序的DS。
当设计手机通讯录这种对内存要求很高的应用时候,需要考虑存储空间而且手机通讯录需要元素有序。哈希表无序,需要额外的空间和时间去排序,而BST就不需要额外的空间去
排序,而且在n<5000条记录的时候,BST的O(nlogn)足够快。

所以应该采用BST。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值