现在的位置: 首页 > 综合 > 正文

二叉排序树(BST) 小讲 【 理解 + 例题 】 更新ing …

2019年02月19日 ⁄ 综合 ⁄ 共 1834字 ⁄ 字号 评论关闭

    很多时候会去忘记,你真正在乎的,是什么、、、

    set 就是用BST来维护集合的一个容器,书上根本没讲、、、、

    定义:二叉排序树(Binary Sort Tree)又称二叉查找树(Binary Search Tree),亦称二叉搜索树。 它或者是一棵空树;或者是具有下列性质的二叉树: (1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值; (2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值; (3)左、右子树也分别为二叉排序树。(4)中序遍历二叉排序树,所得的中序序列是一个递增的有序序列。

    BST的平均时间复杂度为O(log2n),最坏的情况下,会增加至O(n),在刚开始接触BST的时候,我一直觉得是O(n)了 =。= ,那么问题来了,(挖掘机技术到底哪家强)

怎么去优化呢?我觉得会在以后的二叉平衡树(最坏时间复杂度为 log2n )之类的巴拉巴拉的会讲到、、

    建树:(这里仅说明整数序列的建树)对于关键字序列不同,生成的二叉排序树可能不同!(见附 1) 过程:将要插入的与根节点比较,小则归到左子树中,大则归到右子树中,该过程也不难理解的吧,这样经过递归之后,可以建成一个有序的树。代码如下

   

typedef struct node
{
    int key;
    struct node *l, *r;
}bst_node;

bool insert(bst_node * &p, int k) // 这里的引用传递到现在才弄懂,也是醉了、、
{
    if(p == NULL) // 若原树为空,则将新插入的元素作为根节点
    {
        p = (bst_node *)malloc(sizeof(bst_node));
        p -> key = k;
        p -> l = p -> r = NULL;
        return true;
    }
    else if(k == p -> key)
    {
        return false;
    }
    else if(k < p -> key)
        return insert(p -> l, k);
    else
        return insert(p -> r, k);
}

bst_node * creat(int a[], int n)
{
    int i = 0;
    bst_node *bt = NULL;
    while(i < n)
    {
        insert(bt, a[i]);
        i ++;
    }
    return bt;
}

    查找:查找的过程,其实更像是二分查找,对于关键字序列不同的树,平均查找长度也不同,时间复杂度为O(log2n).

   

bst_node * search(bst_node *bt , int k)
{
    if(bt == NULL || bt -> key == k)
        return bt;
    if(k < bt -> key)
        return search(bt -> l, k);
    else
        return search(bt -> r, k);
}

    删除:个人感觉删除这里还是比较难理解的,不仅仅是指针的移动,删除之前必须进行查找,要考虑多种情况(见附 2),个人感觉海狮模拟一遍比较好,书上的模拟占了好大的一部分、、、

    1、需要删除的节点没有左儿子,那么就把右儿子提上去。

    2、需要删除的节点的左儿子没有右儿子,那么就把左儿子提上去。

    3、以上两种都不满足,就把左儿子子孙中最大的节点提到需要删除的节点上。

   下面摘自书上,感觉写的有点麻烦啊、、、

int delete(bst_node * &bt, int k)
{
    if(bt == NULL)
        return 0;
    else
    {
        if(k < bt -> key)
            return delete(bt -> l, k);
        else if(k > bt -> key)
            return delete(bt -> r, k);
        else
        {
            delete_(bt);
            return 1;
        }
    }
}

void delete_(bst_node * &p)
{
    bst_node * q;
    if(p -> r == NULL)
    {
        q = p;
        p = p -> l;
        free(q);
    }
    else if(p -> l == NULL)
    {
        q = p;
        p = p -> r;
        free(q);
    }
    else
        delete1(p, p -> l);
}

void delete1(bst_node *p, bst_node * &r)
{
    bst_node * q;
    if(r -> r == NULL)
        delete1(p, r -> r);
    else
    {
        p -> key = r -> key;
        q = r;
        r = r -> l;
        free(q);
    }
}

    附 :

    1、 两个序列分别为{5, 2, 1, 6, 7, 4, 8, 3, 9},{1, 2, 3, 4 ,5 , 6, 7, 8, 9}

    如下图:

  

   2、 不同点的删除方法。

   如下图:

   

抱歉!评论已关闭.