大话数据结构学习笔记 - 查找之二叉排序树(Binary Sort Tree)及其C实现

大话数据结构学习笔记 - 查找之二叉排序树(Binary Sort Tree)及其C实现

二叉排序树

大话数据结构学习笔记 - 查找之二叉排序树(Binary Sort Tree)及其C实现_第1张图片

二叉排序树(Binary Sort Tree):又称为 二叉查找树, 它或者是一个空树,或者是具有下列性质的二叉树

  • 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值
  • 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值
  • 它的左、右子树也分别为二叉排序树

二叉排序树主要是为了提高查找和插入删除关键字的速度

二叉树结构

/* 二叉树的二叉链表结点结构定义 */
typedef struct BiTNode         /* 结点结构 */
{
    int data;                  /* 结点数据 */
    struct BiTNode *lchild, *rchild;   /* 左右孩子指针 */
}BiTNode, *BiTree;

查找

/*
 * 递归查找二叉排序树 T 中是否存在 key, 指针 f 指向 T 的双亲, 其初始调用值是 NULL. 若查找成功, 则指针 p 指向该数据元素结点, 并返回 TRUE
 * 否则 指针 p 指向查找路径上访问的最后一个结点并返回 FALSE
 *
 */
Status SearchBST(BiTree T, int key, BiTNode *f, BiTNode **p)
{
    if(!T)  /* 查找不成功 */
    {
        *p = f;
        return FALSE;
    }
    else if(key == T->data)  /* 查找成功 */
    {
        *p = T;
        return TRUE;
    }
    else if(key < T->data)
        return SearchBST(T->lchild, key, T, p);  /* 在左子树中继续查找 */
    else
        return SearchBST(T->rchild, key, T, p);  /* 在右子树中继续查找 */
}

插入

/*
 * 当二叉排序树 T 中不存在关键字等于 key 的数据元素时, 插入 key 并返回 TRUE, 否则返回 FALSE
 */
Status InsertBST(BiTree *T, int key)
{
    BiTNode *p, *s;
    if(!SearchBST(*T, key, NULL, &p))  /* 查找不成功 */
    {
        s = CreateBiTNode(key);
        if(!p)
            *T = s;  /* 插入 s 为新的根节点 */
        else if(key < p->data)
            p->lchild = s;  /* 插入 s 为左孩子 */
        else
            p->rchild = s;  /* 插入 s 为右孩子 */
        return TRUE;
    }
    return FALSE;  /* 树中已有关键字相同的结点, 不再插入 */
}

删除

/*
 * 从二叉排序树中删除节点 p, 并重接它的左或右子树
 */
Status Delete(BiTNode **p)
{
    BiTNode *q, *s;
    if((*p)->lchild == NULL)  /* 若右子树为空,则只需重接它的左子树 */
    {
        q = *p;
        *p = (*p)->rchild;
        free(q);
    }
    else if((*p)->rchild == NULL)  /* 若左子树为空,则只需重接它的右子树 */
    {
        q = *p;
        *p = (*p)->lchild;
        free(q);
    }
    else  /* 左右子树均不空 */
    {
        q = *p;
        s = (*p)->lchild;  /* s 为其左子树 */
        while(s->rchild)   /* 转左,寻找其左子树最右结点, 即寻找待删结点的前驱 */
        {
            q = s;
            s = s->rchild;
        }
        (*p)->data = s->data;  /* s 指向被删结点的直接前驱 */
        if(q != (*p))
            q->rchild = s->lchild;  /* 重接 q 的右子树 */
        else
            q->lchild = s->lchild;  /* 重接 q 的左子树 */
        free(s);
    }
    return TRUE;
}

/*
 * 若二叉排序树 T 中存在关键字等于 key 的数据元素时, 则删除该数据元素结点, 并返回 TRUE; 否则返回 FALSE.
 */
Status DeleteBST(BiTree *T, int key)
{
    if(!(*T))       /* 不存在关键字等于 key 的数据元素 */
        return FALSE;
    else if(key == (*T)->data)    /* 找到关键字等于 key 的数据元素 */
        return Delete(T);
    else if(key < (*T)->data)
        return DeleteBST(&(*T)->lchild, key);
    else
        return DeleteBST(&(*T)->rchild, key);
}

复杂度

大话数据结构学习笔记 - 查找之二叉排序树(Binary Sort Tree)及其C实现_第2张图片

若二叉排序树比较平衡,即其深度与完全二叉树相同,均为 log2n+1 ⌊ l o g 2 n ⌋ + 1 ,类似于上图左图 那么查找的时间复杂度就为 O(logn) O ( l o g n ) , 近似于折半查找。若插入序列以排好序,则最坏情况类似于上图右图,时间复杂度为 O(n) O ( n ) , 等同于顺序查找。

代码

Binary Search Tree

结语

如上复杂度分析,二叉排序树的超照性能取决于二叉排序树的形状,但其形状不确定,取决于输入序列。如何构建一个平衡的二叉排序树呢?请看下节文章 平衡二叉树

你可能感兴趣的:(C,算法,数据结构)