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

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

    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、 不同点的删除方法。

   如下图:

   


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
(1)非递归定义 (tree)是由n(n≥0)个结点组成的有限集合。n=0的称为空;n>0的T: ① 有且仅有一个结点n0,它没有前驱结点,只有后继结点。n0称作的根(root)结点。 ② 除结点外n0 , 其余的每一个结点都有且仅有一个直接前驱结点;有零个或多个直接后继结点。 (2)递归定义 一颗大分成几个大的分枝,每个大分枝再分成几个小分枝,小分枝再分成更小的分枝,… ,每个分枝也都是一颗,由此我们可以给出的递归定义。 (tree)是由n(n≥0)个结点组成的有限集合。n=0的称为空;n>0的T: ① 有且仅有一个结点n0,它没有前驱结点,只有后继结点。n0称作的根(root)结点。 ② 除根结点之外的其他结点分为m(m≥0)个互不相交的集合T0,T1,…,Tm-1,其中每个集合Ti(0≤i<m)本身又是一棵,称为根的子(subtree)。 2、掌握的各种术语: (1) 父母、孩子与兄弟结点 (2) 度 (3) 结点层次、的高度 (4) 边、路径 (5) 无序、有序 (6) 森林 3、二的定义 二(binary tree)是由n(n≥0)个结点组成的有限集合,此集合或者为空,或者由一个根结点加上两棵分别称为左、右子的,互不相交的二组成。 二可以为空集,因此根可以有空的左子或者右子,亦或者左、右子皆为空。 4、掌握二的五个性质 5、二的二链表存储。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值