データ構造 - 検索 - バイナリ・ソートを探します

0、なぜバイナリ・ソートツリー

ので、静的な外観です私たちの前に検索データセットが整然と保存されている見つけるには、いくつかの方法、使用バイナリ、補間、フィボナッチ、などがありますが、しかしため、挿入で、効率的、秩序と削除操作のとそれは高くありません。
その後、我々は、動的な検索方法を必要とする効率的な実装のためのいずれかの外観、および優れた挿入、削除効率を作ることができ、その後、我々はバイナリ・ソートツリーを考慮することができます

1、バイナリ・ソートツリー(バイナリソートの木)

また、空のツリーまたは以下の特性を有する二分木のいずれかである二分探索木として知られています。

1)その左の部分木が空でない場合、すべての値が木の左の子ノードは、ルート構造の値未満です。

2)それは右サブツリーを空でない場合、すべてのノードの値の右の部分木は、ルート構造の値よりも大きいです。

3)その左及び右サブツリーは、バイナリソートツリー(再帰的)です。

我々が得るデータが乱れ、私たちは道バイナリ・ソートツリーの組織に従っているが、行きがけのバイナリツリーが発注されます。もちろん、バイナリ・ソートツリーを構築する方が客観将来、挿入、削除、キーワードでの速度を簡単に見つけることができます。

1)検索:

/*
BiTree T    我们要搜索的二叉树
ElemType key我们要搜索的关键字
BiTree F    记录下我们的当前搜索子树的双亲结点
BiTree* P    当我们插入之前,会先搜索是否存在数据,若存在,不插入,若不存在,我们通过这个可以获取我们要插入的位置,直接插入即可
*/
Status SearchBST(BiTree T, ElemType key, BiTree F, BiTree* P)
{
    if (!T)
    {
        *P = F;        //若是未找到则返回父节点位置
        return FALSE;
    }
    else
    {
        if (T->data == key)
        {
            *P = T;    //若是找到则P返回该结点位置
            return TRUE;
        }
        else if (T->data < key)
            return SearchBST(T->rchild, key, T, P);
        else
            return SearchBST(T->lchild, key, T, P);
    }
}

2)插入

Status InsertBST(BiTree* T, int key)
{
    BiTree P,s;
    if (!T)
        return ERROR;
    if (!SearchBST(*T, key, NULL, &P))
    {
        //没有查找到有重复数据,获取到了应该插入的位置
        s = (BiTree)malloc(sizeof(BiTNode));
        s->data = key;
        s->lchild = s->rchild = NULL;
        if (!P)    //空树
            *T = s;
        else if (key < P->data)    //插入左子树
            P->lchild = s;
        else
            P->rchild = s;
        return OK;
    }
    else
        return ERROR;
}

3)删除

如果是叶子结点,则直接删除;

如果结点只存在左子树或右子树,则直接补上;

如果同时存在左子树和右子树,则按照中序遍历的顺序将删除结点的前驱或者后继补上即可;

Status Delete(BiTree* T)
{
    BiTree q,f;
    if (!*T)
        return ERROR;
    if (!(*T)->lchild)    //若是左子树不存在,我们只需要接到右子树
    {
        q = *T;
        *T = (*T)->rchild;
        free(q);
    }
    else if (!(*T)->rchild)    //若右子树不存在,接入左子树
    {
        q = *T;
        *T = (*T)->lchild;
        free(q);
    }
    else  //两边都存在,我们可以选择将右子树最小,或者左子树最大接入,这里选择右子树最小
    {
        f = *T;    //f指向q的双亲结点
        q = (*T)->rchild;
        while (q)
        {
            f = q;
            q = q->lchild;    //找到右子树最小,注意其可能存在右子树,我们要进行保存,接入其父节点
        }
        //将最小的数据更新到根节点处即可,然后记录最小点处,删除即可
        (*T)->data = q->data;
        if (f != (*T))
            f->lchild = q->rchild;
        else
            f->rchild = q->rchild;    //当右子树是一个右斜树
        free(q);
    }
    return TRUE;
}

Status DeleteBST(BiTree* T, int key)
{
    if (!*T)
        return ERROR;
    else
    {
        if ((*T)->data == key)    //找到了,开始删除
        {
            //删除该结点,由于要分情况讨论,所以另外写一个函数
        }
        else if ((*T)->data < key)
            DeleteBST(&(*T)->rchild, key);
        else
            DeleteBST(&(*T)->lchild, key);
    }
}

 

おすすめ

転載: www.cnblogs.com/lemonzhang/p/12396491.html