二叉排序树的查找、插入和删除

二叉排序树(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, BiTree f, BiTree *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)
{
    BiTree p, s;
    if( !SearchBST(*T, key, NULL, &p) )
    {
        s = (BiTree)malloc(sizeof(BiTNode));
        s->data = key;
        s->lchild = s->rchild = NULL;
        
        if( !p )       
        {
            *T = s;     // 插入 s 为新的根结点
        }
        else if( key < p->data )
        {
            p->lchild = s;  // 插入 s 为左孩子
        }
        else
        {
            p->rchild = s;  // 插入 s 为右孩子
        }
        return TRUE;
    }
    else
    {
        return FALSE;   // 树中已有关键字相同的结点,不再插入
    }
}

删除:

Status DeleteBST(BiTree *T, int key)
{
    if( !*T )
    {
        return FALSE;
    }
    else
    {
        if( key == (*T)->data )
        {
            return Delete(T);
        }
        else if( key < (*T)->data )
        {
            return DeleteBST(&(*T)->lchild, key);
        }
        else
        {
            return DeleteBST(&(*T)->rchild, key);
        }
    }
}

Status Delete(BiTree *p)
{
    BiTree q, s;
    
    if( (*p)->rchild == NULL ) //需要删除的节点没有右子树时,直接用该节点的左子树覆盖该节点
    {
        q = *p;//q用来记录需要删除的节点
        *p = (*p)->lchild;
        free(q);
    }
    else if( (*p)->lchild == NULL )//需要删除的节点没有左子树时,直接用该节点的左子树覆盖该节点
    {
        q = *p;
        *p = (*p)->rchild;
        free(q);
    }
    else//需要删除的节点既有左子树又有右子树时,可用其前驱节点A的值替换该节点的值,并用其前驱节点A的左子树覆盖节点A
    {
        q = *p; //q用来记录其前驱节点的双亲节点
        s = (*p)->lchild;
        
        while( s->rchild )
        {
            q = s;
            s = s->rchild;
        }
        
        (*p)->data = s->data;
        
        if( q != *p )
        {
            q->rchild = s->lchild;
        }
        else
        {
            q->lchild = s->lchild;
        }
        
        free(s);
    }
    
    return TRUE;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章