数据结构之二叉搜索树

二叉搜素树,又名二叉查找树,二叉排序树。
它具有以下特点:
1、若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
2、若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
3、它的左、右子树也分别为二叉排序树。
下面我们实现以下二叉搜索树的一些基本操作:
1、初始化
2、销毁
3、插入
4、删除
5、查找

首先我们要先构建一个搜索二叉树的结构体,里面含有一个元素,两个结构体指针,一个指向左子树,一个指向右子树。

typedef struct SearchTreeNode{
    SearchTreeType data;
    struct SearchTreeNode* lchild;
    struct SearchTreeNode* rchild;
}SearchTreeNode;

1、初始化
初始化的操作就是把二叉搜索树置为空树。

void SearchTreeInit(SearchTreeNode** root)
{
    if(root == NULL)
    {
        return;
    }
    *root = NULL;
    return;
}

2、销毁
将根结点free掉,再将根结点指向空。

void SearchTreeDestory(SearchTreeNode** root)
{
    if(root == NULL)
    {
        return;
    }
    free(*root);
    *root = NULL;
}

3、插入
当二叉树为空时,创建一个节点,将根结点指向新节点。
当二叉树不为空时,定义一个ret节点,根结点指向ret节点。将我们插入的元素与ret->data进行比较,如果大于ret->data,那么就递归访问它的右子树,如果小于ret->data,那么就递归的访问它的左子树。直到找到要插入的合适位置进行插入。

void SearchTreeInsert(SearchTreeNode** root,SearchTreeType to_insert)
{
    if(root == NULL)
    {
        return;
    }
    if(*root == NULL)
    {
        SearchTreeNode* newnode = SeaechTreeCreate(to_insert);
        *root = newnode;
    }
    SearchTreeNode* ret = *root;
    if(to_insert > ret->data)
    {
        SearchTreeInsert(&ret->rchild,to_insert);
    }
    else if(to_insert < ret->data)
    {
        SearchTreeInsert(&ret->lchild,to_insert);

    }
    else
    {
        return;
    }
}

4、删除
按给定的元素值进行删除,首先我们要先找到这个元素,定义一个节点cur,让根结点指向cur。然后一直递归的进行比较,直到找到要删除的元素值。
要删除的元素的位置还要分为四种情况:
1、左子树,右子树都为空
此情况下将元素的父节点直接指向NULL,再free掉这个元素就可以了。
2、左子树不为空,右子树为空
此情况下将元素的父节点指向元素的左子树,free掉元素。
3、左子树为空,右子树不为空
此情况下将元素的父节点指向元素的右子树,free掉元素。
4、左子树不为空,右子树也不为空
此情况下,我们要将删除的这个元素与它的右子树中最小的值进行交换后删除。

void SearchTreeMove(SearchTreeNode** root,SearchTreeType to_delete)
{
    if(root == NULL)
    {
        return;
    }
    if(*root == NULL)
    {
        return;
    }
    SearchTreeNode* cur = *root;
    if(to_delete > cur->data)
    {
       return  SearchTreeMove(&cur->rchild,to_delete);
    }
    if(to_delete < cur->data)
    {
       return  SearchTreeMove(&cur->lchild,to_delete);
    }
    else
    {
        if(cur->lchild == NULL && cur->rchild == NULL)
        {
            *root = NULL;
            free(cur);
            cur = NULL;
            return;
        }
        else if(cur->lchild != NULL && cur->rchild == NULL)
        {
            *root = cur->lchild;
            free(cur);
            cur = NULL;
            return;
        }
        else if(cur->lchild == NULL && cur->rchild != NULL)
        {

           *root = cur->rchild;
           free(cur);
           cur = NULL;
           return;
        }
        else
        {
            SearchTreeNode* min = cur->rchild;
            while(cur->lchild != NULL)
            {
                min = min->lchild;
            }
            cur->data = min->data;
            SearchTreeMove(&cur->rchild,min->data);
            free(min);
            min = NULL;
            return;


        }
}
}

5、查找
查找就是递归的进行比较要查找的元素值和二叉树的所有元素值,直到找到,再返回这个值。

SearchTreeNode* SearchTreeFind(SearchTreeNode* root,SearchTreeType to_find)
{
    if(root == NULL)
    {
        return NULL;
    }
    if(to_find > root->data)
    {
        SearchTreeFind(root->rchild,to_find);
    }
    else if(to_find < root->data)
    {
        SearchTreeFind(root->lchild,to_find);
    }
    else
    {
        return root;
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值