数据结构第四周笔记(1)——树(中)(慕课浙大版本--XiaoYu)

210 阅读5分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第17天,点击查看活动详情

4.1 二叉搜索树

4.1.1 二叉搜索树及查找

查找问题:
    1.静态查找与动态查找
    2.针对动态查找,数据如何组织
    
    什么是二叉查找树:直接把元素放在树上,不要放在数组里面。
    好处:树的动态性比较强,要插入删除比在线性里面做要方便

二叉搜索树(BST)

BST=>Binary Search Tree
​
也称为二叉排序树或者二叉查找树
​
二叉搜索树:一颗二叉树,可以为空;如果不为空,满足以下性质:
1.非空左子树的所有键值小于其根结点的键值。
2.非空右子树的所有键值大于其根结点单独键值
3.左、右子树都是二叉搜索树

image-20220702012825394

image-20220702012726729

二叉搜索树操作的特别函数:

image-20220702012904895

插入(新结点x)删除(x这个结点)

image-20220702013012616

二叉搜索树的查找操作:Find

查找从根结点开始,如果树为空,返回NULL
​
若搜索树非空,则根结点关键字和X进行比较,并进行不同处理:
    1.若X小于根结点赋值,只需在左子树中继续搜索;
    2.如果X大于根结点的键值,在右子树中进行继续搜索;
    3.若两者比较结果是相等,搜索完成,返回指向此结点的指针
代码实现
Position Find(ElementType X,BinTree BST)
{
    if(!BST) return NULL;//查找失败
    if( X > BST -> Data)//这是尾递归,下面的两个Find的也是同理
        return Find(X,BST->Right);//在右子树中继续查找
    Else if(X < BST -> Data)
        return Find(X,BST->Left);//在左子树中继续查找
    else//X == BST->Data
        return BST;//查找成功,返回结点的找到结点的地址
}
​
​
//由于非递归函数的执行效率高,可将"尾递归"函数改为迭代函数
Position IterFind(ElementType X,BinTree BST)
{
    while(BST){
        if(X > BST->Data)
            BST = BST -> Right;//向右子树中移动,继续查找
        else if(X < BST->Data)
            BST = BST ->Left;//向左子树中移动,继续查找
        else//X == BST ->Data
            return BST;//查找成功,返回结点的找到结点的地址
    }
        return NULL;//查找失败
}
​
//查找的效率决定于树的高度

查找最大和最小元素

1.最大元素一定是在树的最右分枝的端结点上
2.最小元素一定是在树的最左分枝的端结点上
​
对于搜索树的最大元素结点,下面哪个说法是正确的?
A.
一定是叶结点
B.
一定没有左儿子
C.
一定没有右儿子
D.
是后序遍历的最后一个结点
答案是:C
查找最小元素的递归函数
Position FindMin( BinTree BST)
{
    if(!BST) return NLULL;//空的二叉树,返回NULL
    else if(!BST->Left)
        return BST;//找到最左结点并返回
    else
        return FindMin(BST->Left);//沿左分支继续查找
}
查找最大元素的迭代函数
Position FindMax( BinTree BST)
{
    if( BST )
        while( BST -> Right ) BST = BST->Right;//沿右分支继续查找,直到最右叶结点
    return BST;
}

4.1.2 二叉搜索树的插入

【分析】关键是要找到元素应该插入的位置,可以采用与Find类似的方法

image-20220702015511291

二叉搜索树的插入算法

BinTree Insert(ElementType X,BinTree BST)
{
    if(!BST){
        //若原树为空,生成并返回一个结点的二叉搜索树
        BST = malloc(sizeof(struct TreeNode));
        BST -> Data = X;
        BST -> Left = BST -> Right = NULL;
    }else //开始找要插入元素的位置
        if(X < BST->Data )
            BST -> Left = Insert(X,BST->Left);//递归插入左子树
    else if(X > BST->Data)
        BST->Right = Insert(X,BST->Right);//递归插入右子树
    //else X已经存在,什么都不做
    return BST;
}

image-20220702021901357

image-20220702021921682

4.1.3 二叉搜索树的删除

考虑三种情况

  1. 要删除的是叶结点:直接删除,并再修改其父节点指针---置为NULL

  2. 要删除的结点只有一个孩子结点:

    1. 将其父节点的指针指向要删除结点的孩子结点
    2. image-20220702025452840
    3. image-20220702025522322
  3. 要删除的结点有左、右两颗子树:

    1. 用另一结点代替被删除结点:右子树的最小元素或者左子树的最大元素
    2. image-20220702025716832 取右子树中的最小元素替代
    3. image-20220702025939253
    4. image-20220702030039570
    5. 代码实现
    BinTree Delete (ElementType X,BinTree BST)
    {
        Position Tmp;   
        if(!BST) printf("要删除的元素未找到");
        else if(X < BST ->Data)
            BST->Left = Delete(X,BST->Left);//左子树递归删除,返回左子树删除了x这个结点之后,新的左子树根结点的地址
        else if(X > BST->Data)
            BST->Right = Delete( X,BST->Right);//右子树递归删除
        else//找到要删除的结点
            if(BST->Left && BST->Right ){//被删除结点有左右两个子节点
                Tmp = FindMin(BST->Right);//在右子树中找最小的元素填充删除结点
                BST->Data = Tmp->Data;
                BST->Right = Delete(BST->Data,BST->Right);//在删除结点的右子树中删除最小元素
            }else{//被删除结点有一个或无子结点
                Tmp = BST;
                if(!BST->Left)//有右孩子或无子结点
                    BST = BST->Right;
                else if(!BST->Left)//有左孩子或无子结点
                    BST = BST->Left;
                free(Tmp);
            }
    }
    return BST;
    

4.2 平衡二叉树

4.2.1 什么是平衡二叉树

image-20220702032658211

怎么样子算基本上平衡:1.左右结点差不多2.左右高度差不多

平衡因子

image-20220702032941579

平衡因子是对结点来说的,左右的一个高度差我们就称为平衡因子

平衡二叉树(Balanced Binary Tree)(AVL树) AVL是提出这个的科学家名字的第一个字母
空树,或者任一结点左、右子树高度差的绝对值不超过1,即|BF(T)|<=1

image-20220702040217888

image-20220702040552776

画画看,至少需要多少个结点才能构造出一棵4层(h=3)的平衡二叉树?7个

image-20220702041010879

image-20220702041413070

4.2.2 平衡二叉树的调整

RR旋转

image-20220702050945421

image-20220702051127034

image-20220702051214039

LL旋转

image-20220702051315347

image-20220702051544173

LR旋转

image-20220702051645639

image-20220702051833406

image-20220702052115268

RL旋转

image-20220702052247419

image-20220702052510229

小测试

image-20220702042025929