数据结构(第四章)

树中
一.二叉搜索树(BST,Binary Search Tree)
二叉搜索树也称二叉排序树(因为它有一定的顺序在里面)或二叉查找树(因为里面的某些规律方便查找),可以为空。
不为空时的性质:
非空左子树的所有键值小于其根结点的键值;
非空右子树的所有键值大于其根结点的键值;
左,右子树都是二叉搜索树。
既然叫二叉查找树,那我们就来看看它的查找吧!
二叉搜索树的查找
查找过程:我们先从根结点开始,如果为空,则返回NULL;非空的话我们将关键字X进行比较。
若小于根结点的键值,则在左子树进行递归查找,否则就是右子树,这是性质,若相同就返回
该结点的指针。

Position Find(ElementType X,BinTree BST)
{
    if(!BST)//查找失败
    {
        return NULL;
    }
    if(X>BST->data)//大于,则在右子树中查找
    {
        return Find(X,BST->Right);
    }
    else if(X<BST->data)//小于,则在左子树中查找
    {
        return Find(X,BST->Left);
    }
    else//等于,则返回结点指针
    {
        return BST;
    }
}

改进:因为非递归函数的执行效率高,所以我们可以把递归用循环代替。

Position Find(ElementType X,BinTree BST)
{
    while(BST)
    {
        if(X>BST->data)//大于,则在右子树中查找
        {
            BST=BST->Right;
        }
        else if(X<BST->data)//小于,则在左子树中查找
        {
           BST=BST->Left;
        }
        else//等于,则返回结点指针
        {
            return BST;
        }
    }
    return NULL;//查找失败
}

查找最大元素和最小元素
由于性质,我们很容易就知道
最大元素一定在最右端;最小元素一定在最左端。

Position FindMin(BinTree BST)
{
    if(!BST)//为空,返回NULL
    {
        return NULL;
    }
    else if(!BST->Left)//找到最左端结点
    {
        return BST;
    }
    else
    {
        return FindMin(BST->Left);//沿着左分支继续找
    }
}
Position FindMax(BinTree BST)
{
    if(!BST)//为空,返回NULL
    {
        return NULL;
    }
    else if(!BST->Right)//找到最右端结点
    {
        return BST;
    }
    else
    {
        return FindMin(BST->Right);//沿着右分支继续找
    }
}

二叉搜索树的插入
其实和Find很相像,因为我们得先找到,才能进行插入,但是我们得注意一点,如果是叶结点,我们得主动申请一个空间,然后在跟其根结点比较,看是放左边,还是右边。

BinTree Insert(ElementType X,BinTree BST)
{
    if(!BST)//主动申请
    {
        BST=(struct TreeNode *)malloc(sizeof(struct TreeNode));
        BST->data=X;
        BST->Left=BST->Right=NULL;
    }
    else
    {
        if(X<BST->data)
        {
            BST->Left=Insert(X,BST->Left);
        }
        else if(X>BST->data)
        {
            BST->Right=Insert(X,BST->Right);
        }
        else
            return BST;
    }
}

讲了查找,插入,就该讲删除了吧
二叉搜索树的删除
删除的时候,我们得非常小心,因为我们的结点有三种状态。
叶结点:没有孩子,我们就残忍一点,直接删除,并且修改器父结点的指针为空。
只有一个孩子的结点:将它的父结点直接指向孙子结点,孙子变儿子。
有两个孩子的结点:用另一结点代替删除结点:取右子树最小元素代替或取左子树最大元素代替。孩子多就是麻烦!所以我们会用的之前写的函数!

BinTree Delete(ElementType X,BinTree BST)
{
    Position temp;
    if(!BST)//失败
    {
        printf("删除元素未找到");
    }
    else if(X>BST->data)
    {
        BST->Right=Delete(X,BST->Right);
    }
    else if(X<BST->data)
    {
        BST->Left=Delete(X,BST->Left);
    }
    else
    {
        if(BST->Left&&BST->Right)//带两个孩子
        {
            temp=FindMin(BST->Right);
            BST->data=temp->data;
            BST->Right=Delete(BSt->data,BST->Right);
        }
        else
        {
            temp=BST;
            if(!BST->Left)
            {
                BST=BST->Right;
            }
            else if(!BST->Right)
            {
                BST=BST->Left
            }
            free(temp);
        }
    }
    else 
    return BST;
}
发布了18 篇原创文章 · 获赞 0 · 访问量 443

猜你喜欢

转载自blog.csdn.net/JT518721/article/details/104411078
今日推荐