数据结构 - 二叉搜索树, AVL树

这几天写OS lab写的焦虑爆棚,好在现在写完了lab4/7. 又忙活哥大入学的事情,最终结论是可以先快乐网课一学期。所以最近都没更新博客,my apologies…

1.二叉搜索树

1.1 定义

一个节点的左后代都比它小,右后代都比它大。
在这里插入图片描述
对BST做中序遍历,是单调非降的。
在这里插入图片描述

1.2 二叉搜索树的查找

在这里插入图片描述
对二叉搜索树做查找,相当于对一个有序向量做二分查找。

TreeNode* search(TreeNode* root, int val){
    
    
    //找到树里值为val的节点,成功时返回该节点,失败时返回NULL
    if(root == NULL) //ooops! missed 
        return NULL;
    if(root->val == val)
        return root;
    if(root->val<val)
        search(root->rightchild,val);
    if(root->val>val)
        search(root->leftchild,val);
}

[Alert] 在递归函数中,一定要先考虑节点为NULL的问题,否则访问一个NULL节点的val就会出问题的!!

1.3 二叉搜索树的插入

在这里插入图片描述

void insert(TreeNode* & root, int val){
    
    
    if((root->leftchild == nullptr) && (val< root->val)){
    
    //find a node to insert!
        root->leftchild = new TreeNode(val);
        return;
    }
    if((root->rightchild == nullptr) && (val> root->val)){
    
     //find a node to insert!
        root->rightchild = new TreeNode(val);
        return;
    }
    if(root->val == val){
    
     //oooops! already exist
        return;
    }
    if(val>root->val){
    
     //deep into right child...
        insert(root->rightchild,val);
    }
    if(val<root->val){
    
     //deep into left child...
        insert(root->leftchild,val);
    }

}

1.4 二叉搜索树的删除

分两种情况讨论:

(1)待删除节点的任一子树为空

只需用那个非空子树来替代待删除节点即可
在这里插入图片描述
(2)待删除节点的两个子树都非空
找到待删除节点在中序遍历下的后继节点(先向右迈一步,然后一直向左)。在这里,这个后继节点应该是比待输出节点大的第一个。将他们交换。
这样,问题就转化为了情况(1),因为现在待删除节点一定没有左孩子。
在这里插入图片描述

1.5 平衡

1.5.1 二叉搜索树的期望树高

我们用两个方法来看二叉搜索树的期望树高。

  • 随机生成法来看
    在这里插入图片描述

  • 随机组成法来看
    在这里插入图片描述

    扫描二维码关注公众号,回复: 13145851 查看本文章

O(logn)和O(sqrt(n))还是差着很多的啊!那么,BST的期望树高到底是多少呢?
在这里插入图片描述

1.5.2 理想和适度平衡
  • 理想平衡 – 满树:叶节点只能出现在最底部的两层,这个条件过于严苛
    在这里插入图片描述
  • 适度平衡 – 高度为O(logn)的二叉搜索树,叫做平衡二叉搜索树(BBST)
    在这里插入图片描述
1.5.3 等价变换

观察如下的两个树,发现它们虽然连接关系不相同,但是中序遍历序列完全一致,说明它们是等价的BST。
**加粗样式**
利用这一性质,可以知道,BST通过若干次旋转(O(logn))可以变成BBST.
在这里插入图片描述
具体做法:旋转调整 – zigzag
在这里插入图片描述

2. AVL树

2.1 定义

对于任何一个节点,其左孩子和右孩子的高度之差需要<=1。
在这里插入图片描述

2.2 AVL树的树高

可以证明,AVL树虽然不是理想平衡,但一定是适度平衡的(树高O(logn))

证明:
在这里插入图片描述

将一棵高度为h的树包含的节点数目记作S(h). 由于这是一棵AVL树,所以左右孩子高度相差不超过1. 因此有:
在这里插入图片描述
反过来,由n个节点构成的AVL树,高度不超过O(logn).

2.3 AVL树的插入

插入是一个比较复杂的问题,因为从被插入节点的祖父开始,每个祖先都有可能失衡,且可能同时失衡!
在这里插入图片描述
但好消息是,我们可以利用旋转变换将其重平衡,因为树高为O(logn),所以只需要O(logn)的时间就可以将其变成平衡的AVL树。

  • 单旋
    在这里插入图片描述
  • 双旋
    在这里插入图片描述

2.4 AVL树的删除

在这里插入图片描述

  • 单旋
    在这里插入图片描述

  • 双旋
    在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_41332009/article/details/115256975
今日推荐