二叉查找树

Binary Search Tree,也称有序二叉树(ordered binary tree),排序二叉树(sorted binary tree),是指一棵空树或者具有下列性质的 二叉树 :
1. 若任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
2. 任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
3. 任意节点的左、右子树也分别为二叉查找树。

比如:

这样的结构有一个好处是很容易获得最大值(Maximum)、最小值(minimum)、某元素的前驱(Precursor)、某元素的后继(Successor)。

最大值:树的最右节点。

最小值:树的最左节点。

某元素前驱:左子树的最右。

某元素的后继:右子树的最左。


基本操作

二叉搜索树的基本操作包括searching、traversal、insertion以及deletion。

pseudocode:

① searching

复制代码
tree * search_tree(tree *l, item_type x){
    if(l == null) return NULL;
    if(l->item == x) return l;
    if(x < l->item){
        return (search_tree(l->left, x));
    }   
    if(x > l->item){
        return (search_tree(l->right, x));
    }
}
复制代码

时间复杂度为O(h),h为树的高度。

② traversal

由于小的节点在左边,大的节点在右边,因此使用中序(in-order)遍历可以方便的得到一个sorted list。

复制代码
void traverse_tree(tree *l){
    if(l != NULL){
        traverse_tree(l->left);
        process_item(l->item);
        traverse_tree(l->right);
    }
}
复制代码

时间复杂度为O(n),n为树的总结点数。

③ insertion二叉查找树的插入过程如下:1.若当前的二叉查找树为空,则插入的元素为根节点,2.若插入的元素值小于根节点值,则将元素插入到左子树中,3.若插入的元素值不小于根节点值,则将元素插入到右子树中。

复制代码
insert_tree(tree **l, item_type x, tree *parent){
    tree *p; /*temporary pointer*/
    if(*l == NULL){
        p = malloc(sizeof(tree));
        p->item = x;
        p->left = p->right = NULL;
        p->parent = parent;
        *l = p;
        return;
    }
    if(x < (*l)->item){
        insert_tree(&((*l)->left), x, *l);
    }else{
        insert_tree(&((*l)->right), x, *l);
    }
}
复制代码

时间复杂度为O(h),h为树的高度。

④deletion

在删除节点时有三种情况:

1)要删除的节点为叶节点

  那么直接删除即可。

2)要删除的节点有一个子节点

  那么删除掉该节点,并用其唯一的子节点代替自己的位置即可。

3)要删除的节点有两个子节点

  那么首先要找到该节点的右子树的最小值节点k,然后将该k替换掉待删除节点。

最坏情况下,时间复杂度为O(h)+指针的移动开销。

 

进阶

由上可知,二叉搜索树的dictionary operation(包括search、insertion、deletion)的时间复杂度均与O(h)相关,h为树的高度(log n),如果按照上述的insertion方法构建树,那么构建出来的树的形状各异,特别是当输入序列有序时,更会退化到链表的程度。所以,如果能用某种方法,将树的高度降低到最小,那么其dictionary operation的时间开销均可以降低,不过相对而言构建树的开销将增大。为了降低二叉搜索树的高度而提出了平衡二叉树(Balanced Binary Tree)的概念。它要求左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。这样就可以将搜索树的高度尽量减小。常用算法有红黑树、AVL、Treap、伸展树等。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值