动态查找-二叉排序树和平衡二叉树

1.二叉排序树

二叉排序树或者是一颗空树,或者是具有以下性质的树:(1 )如果根节点的左子树不为空,则左子树的所有结点的值均小于它的根节点的值;(2 )如果它的右子树不空,右子树的节点的值都大于根节点的值;(3 )对于左右子树,也是二叉排序树。

二叉排序树又称二叉查找树,查找算法很简单,从根节点开始对比,如果要查找的值e和根节点g的值相等,返回指向根节点的指针;如果e < g,就递归在左子树查找;如果e > g,就递归在右子树查询。如果查找到叶子结点还未找到,说明查找失败。

二叉排序树是一种动态树。树的结构通常不是一次生成的,而是在查找的过程中,当树中不存在所要查找的值时,将对应的值的节点插入。显然新插入的节点是叶子结点。

bool searchBST(BTree *T, BTree *p, int key){
    if(!T){
        return false;
    }
    p = T;
    if(key == T -> key)
        return true;
    if(key < T -> key)
        searchBST(T -> left, p, key);
    else
        searchBST(T -> right, p, key);
}

void insertBST(BTree *T, int key){
    BTree *p = NULL;
    if(!searchBST(T, p, key)){
        BTree *q = new BTree(key);
        if(!p)
            T = q;
        else if(p -> key > key)
            p -> left = q;
        else
            p -> right = q;
    }
}

如果中序遍历二叉排序树,可以得到一个有序序列。如果需要在二叉排序树上删除一个节点,只要保证删除节点后依旧保持二叉排序树的特性就可以。二叉排序树的ASL(平均查找长度)与logn同数量级。

2.平衡二叉树

又称AVL树,它或者是一颗空树,或者是具有以下性质的二叉树:左右子树都是平衡二叉树,且左右子树的深度差的绝对值<=1。节点的左子树的深度减去右子树的深度成为平衡因子。AVL树的深度和logn同数量级,将二叉排序树建立成平衡二叉树,由此它的平均查找长度也是和logn同数量级。

一般情况下,在二叉排序树上因为插入节点而导致失去平衡,失去平衡的最小子树根节点指针设为a,失衡后分为以下4种情况来调整。

1.LL型,单项右旋平衡处理,由于a的左子树根节点的左子树上插入节点而失衡,a的平衡因子由1变成了2,需要一次向右的顺时针旋转操作。将a的左子树的根节点b作为新的根节点而代替a,b的右子树作为a的左子树,a在作为b的右子树的根节点。

《动态查找-二叉排序树和平衡二叉树》

2.RR型,单向左旋平衡处理,由于a的右子树根节点的右子树上插入节点而失衡,a的平衡因子有-1变成-2,需要一次逆时针的旋转操作。如图,c向左上旋转到a的位置,a的右子树指向c的左子树,然后c的左子树指向a。

《动态查找-二叉排序树和平衡二叉树》

3.LR型,先左后右平衡处理,由于a的左子树的根节点的右子树上插入节点而导致a的平衡因子由1变成2,需要进行两次旋转,先左后右。如下图:先将d左旋转到b的位置,然后再做一次右旋转,旋转到a的位置,并把b的右子树d由a的左指针指向,d的右子树指向a。

《动态查找-二叉排序树和平衡二叉树》

4.RL型,先右后左平衡处理,由于a的右子树的根节点的左子树上插入节点而导致a的平衡因子有-1变成-2,需要进行两次旋转,先右后左。如图:首先将d向右旋转到c的位置,然后向左旋转到a的位置,并且a的右子树指向d的左子树,d的左子树指向a。

《动态查找-二叉排序树和平衡二叉树》

    原文作者:二叉查找树
    原文地址: https://blog.csdn.net/shzxrt/article/details/37708035
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞