【数据结构】6.搜索树

这篇具有很好参考价值的文章主要介绍了【数据结构】6.搜索树。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1.二叉搜索树

1.1 定义

二叉搜索树:

  •  一棵非空的二叉搜索树每个元素都有一个关键字,并且任意两个元素的关键字不同,所有关键字都是唯一的
  • 根节点的左子树小于根节点的关键字
  • 根节点的右子树大于根节点的关键字
  • 左右子树也是二叉搜索树

【数据结构】6.搜索树

索引二叉搜索树:

  源于普通的二叉搜索树,在每个节点中添加一个 leftSize 字段,用来保存该节点左子树的元素个数。

【数据结构】6.搜索树

1.2 二叉搜索树的操作和实现

1.2.1 搜索

根据搜索元素的 theKey 对应向左孩子或右孩子移动寻找即可,时间复杂度为O(height)

【数据结构】6.搜索树

template<class K, class E>
pair<const K, E>* binarySearchTree<K, E>::find(const K& theKey) const
{// 返回关键字时K的元素指针
   // 从根节点 p 开始搜索,寻找关键字为 theKey 的元素
    binaryTreeNode<pair<const K, E> >* p = root;
    while (p != NULL)
        // 检查元素
        if (theKey < p->element.first)
            p = p->leftChild;
        else
            if (theKey > p->element.first)
                p = p->rightChild;
            else // 找到匹配的元素
                return &p->element;

    // 未找到匹配的元素
    return NULL;
}

1.2.2 插入

  使用 pp 指针记录 p 指针的双亲节点,p 指针不断查找应该插入的位置

  • p 指针指向空时,说明该插入到该位置。判断插入元素 theKey 和 pp 指针的大小关系插入该元素
  • p 指针找到相同的 theKey 时,更新该节点的 value

【数据结构】6.搜索树

template<class K, class E>
void binarySearchTree<K, E>::insert(const pair<const K, E>& thePair)
{// 插入thePair节点,如果存在相同的Key则覆盖元素
    binaryTreeNode<pair<const K, E> >* p = root;
    binaryTreeNode<pair<const K, E> >* pp = NULL;

    // 如果循环结束未找到该元素, 则pp元素就是该元素的父节点
    while (p != NULL)
    {// 检查元素p
        pp = p;
        // 将p移动到它的孩子节点
        if (thePair.first < p->element.first)
            p = p->leftChild;
        else
            if (thePair.first > p->element.first)
                p = p->rightChild;
            else
            {// 如果有相同的key, 覆盖旧的值
                p->element.second = thePair.second;
                return;
            }
    }

    // 为thePair创建一个节点, 然后与pp连接
    binaryTreeNode<pair<const K, E> >* newNode = new binaryTreeNode<pair<const K, E> >(thePair);
    if (root != NULL) // 判断树是否是空
        if (thePair.first < pp->element.first)
            pp->leftChild = newNode;
        else
            pp->rightChild = newNode;
    else
        root = newNode; // 直接将节点作为根节点
    treeSize++;
}

1.2.3 删除

  删除分三种情况

  • 要删除的节点没有孩子节点:如左图所示,这种情况只需要找到该节点释放内存空间,并将双亲节点的右孩子指针置为空即可
  • 要删除的节点只有一个孩子节点:如右图所示,这种情况只需要将该节点内存空间释放,并且将 元素15 的左孩子连接到 元素12 的孩子节点即可

【数据结构】6.搜索树

  • 要删除的节点有两个孩子节点,且要更换位置的节点没有孩子节点。我们需要在要删除的节点的左孩子中,向右寻找到最大的元素做替换,将 元素14 重新连接 元素12 和 元素18 构建一个新的树,并重新连接到 元素20 的左孩子位置,最后释放元素14的内存(这种情况实际上转换为构建一棵树,然后删除14,且14没有孩子节点)

【数据结构】6.搜索树

  • 要删除的节点有两个孩子节点,且要更换位置的节点有一个孩子节点。我们需要在要删除的节点的左孩子中,向右寻找到最大的元素做替换,将 元素14 重新连接 元素12 和 元素18 构建一个新的树,并重新连接到 元素20 的左孩子的位置,然后把 元素14 的孩子连接到 元素14 的双亲节点处,释放 元素14 的内存空间(这种情况实际上转换为构建一棵树,然后删除14,且14有一个孩子节点)

【数据结构】6.搜索树文章来源地址https://www.toymoban.com/news/detail-711580.html

template<class K, class E>
void binarySearchTree<K, E>::erase(const K& theKey)
{// 删除关键字为 theKey 的节点

    // 查找关键字为 theKey 的节点
    binaryTreeNode<pair<const K, E> >* p = root;    // p 是要删除的节点
    binaryTreeNode<pair<const K, E> >* pp = NULL;   // pp 是 p 的双亲
    while (p != NULL && p->element.first != theKey)
    {// p移动到它的孩子节点
        pp = p;
        if (theKey < p->element.first)
            p = p->leftChild;
        else
            p = p->rightChild;
    }
    if (p == NULL)
        return; // 未找到则直接结束

    // 找到一个 s 元素替换要删除的元素 p, 然后用元素 s 构建一棵树
    // 接下来转换为删除元素 s 的操作, s 只有左孩子或者没有孩子
    if (p->leftChild != NULL && p->rightChild != NULL)
    {
        binaryTreeNode<pair<const K, E>>* s = p->leftChild; // s: 在 p 的左孩子中找到最大的元素
        binaryTreeNode<pair<const K, E>>* ps = p;           // ps: s 的双亲
        while (s->rightChild != NULL)
        {
            ps = s;
            s = s->rightChild;
        }

        // 用元素 s 构建一棵树, 替代元素 p 的位置
        binaryTreeNode<pair<const K, E> >* q = new binaryTreeNode<pair<const K, E>> (s->element, p->leftChild, p->rightChild);

        // 如果要删除的没有双亲, 根节点就是 q, 否则把孩子节点更换为 q
        if (pp == NULL) { root = q; }
        else if (p == pp->leftChild) { pp->leftChild = q; }
        else { pp->rightChild = q; }

        // 如果 s 恰好是要删除元素 p 的下一个节点, 单独处理一下
        if (ps == p) { pp = q; }
        else { pp = ps; }

        // 释放元素 p 的空间, 把 p 的指针指向 s, 接下来的工作是删除 s
        delete p;
        p = s;
    }

    // 下面的情况: 元素 p 只有一个孩子或者没有孩子
    // 指针 c 指向了元素 p 的孩子或者 NULL
    binaryTreeNode<pair<const K, E> >* c;
    if (p->leftChild != NULL) { c = p->leftChild; }
    else if (p->leftChild != NULL) { c = p->rightChild; }
    else { c = NULL; }

    // 如果要删除的 p 是根节点
    if (p == root)
        root = c;
    else
    {// 否则将 pp 的孩子置为 p
        if (p == pp->leftChild)
            pp->leftChild = c;
        else pp->rightChild = c;
    }
    treeSize--;
    delete p;
}

到了这里,关于【数据结构】6.搜索树的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 数据结构——二叉搜索树

    本章代码:二叉搜索树 二叉搜索树又叫二叉排序树,它具有以下性质: 若左子树不为空,则左子树上所有结点的值都小于根结点的值 若右子树不为空,则右子树上所有结点的值都大于根结点的值 它的左右子树也分别为二叉搜索树 这个结构的时间复杂度为一般人会以为是 O(

    2024年02月12日
    浏览(42)
  • 数据结构---二叉搜索树

    二叉搜索树(Binary Search Tree 简称BST)又称二叉排序树,是一种二叉树的特殊形式,它在每个节点上存储的键值满足以下性质: 若它的左子树不为空,则左子树上的所有节点的 值都小于根节点的值 若它的右子树不为空,则右子树上所有节点的值都大于根节点的值 它的左右子树也

    2024年02月07日
    浏览(42)
  • 【数据结构】二叉搜索树

    二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树: 若它的左子树不为空,则左子树上所有节点的值都小于根节点的值 若它的右子树不为空,则右子树上所有节点的值都大于根节点的值 它的左右子树也分别为二叉搜索树 两种情况: 树为空,则

    2024年01月19日
    浏览(39)
  • 数据结构:搜索二叉树 | 平衡二叉树

    博客写的代码都放在这里:gitee仓库链接 1.二叉搜索树 1.1.基本概念 二叉搜索树又称二叉排序树, 可以为空,如果不为空具有以下性质的二叉树 : 若它的左子树不为空,则左子树上所有节点的值都小于根节点的值 若它的右子树不为空,则右子树上所有节点的值都大于根节点的

    2024年01月23日
    浏览(58)
  • 高级数据结构——二叉搜索树

    目录 1. 二叉搜索树的概念 2. 二叉搜索树的实现 结点类 二叉搜索树的类 2.1 默认成员函数 2.1.1 构造函数 2.1.2 拷贝构造函数 2.1.3 赋值运算符重载函数 2.1.4 析构函数 2.2 中序遍历 2.3 insert插入函数 2.3.1 非递归实现 2.3.2 递归实现 2.4 erase删除函数 2.4.1 非递归实现 2.4.2 递归版本

    2024年02月10日
    浏览(41)
  • 高级数据结构 <二叉搜索树>

    本文已收录至《数据结构(C/C++语言)》专栏! 作者:ARMCSKGT 前面我们学习了二叉树,但仅仅只是简单的二叉树并没有很大的用处,而本节的二叉搜索树是对二叉树的升级,其查找效率相对于简单二叉树来说有一定提升,二叉搜索树是学习AVL树和红黑树的基础,所以我们必须先

    2024年02月04日
    浏览(45)
  • 算法与数据结构--二叉搜索树与自平衡二叉搜索树

    注:字典的 \\\"member运算\\\" 指的是检查字典中是否存在某个特定的键的操作,即查询操作。 如果我们使用数组来实现字典/map,虽然使用二分法查询也可以达到logn,但是的话插入和删除太慢了。使用链表实现的话虽然插入和删除是O(1),但是查询的话达到了O(n),也不可取。 因此人

    2024年02月04日
    浏览(38)
  • 数据结构篇八:二叉搜索树

      前面我们已经学习过了二叉树,二叉搜索树是在二叉树的基础上增添了一些规则,使其能完成快速查找的功能,同时它也帮助我们更好的理解后续将要学习的map和set。   二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树: 若它的左子树不为

    2024年03月13日
    浏览(50)
  • 数据结构之二叉搜索树

    满足条件: 1.对于根节点:左子树中所有节点的值小于右子树中所有节点的值 2.任意节点的左右子树也是二叉搜索树,同样满足条件1 我们将二叉搜索树封装为一个类 BinarySearchTree ,并声明一个成员变量 root ,指向树的根节点 查找节点 给定目标值 target ,我们可以根据二叉搜索

    2024年01月20日
    浏览(37)
  • 【数据结构】二叉搜索树BSTree

    二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树: 若它的左子树不为空,则左子树上所有节点的值都小于根节点的值 若它的右子树不为空,则右子树上所有节点的值都大于根节点的值 左根右 它的左右子树也分别为二叉搜索树 之所以又叫二叉排

    2024年02月03日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包