C++数据结构之二叉搜索树的实现详解

C++数据结构之二叉搜索树的实现详解

1. 什么是二叉搜索树?

二叉搜索树是一种二叉树,其中每个节点都包含一个键值,且每个节点的键值都大于其左子树中任何节点的键值,小于其右子树中任何节点的键值。如下图所示:

        9
       / \
      4   15
         /  \
       12    20

在上面的二叉搜索树中,节点的键值分别是9, 4, 15, 12, 20,且每个节点的键值都符合上述定义。

2. 为什么需要二叉搜索树?

二叉搜索树可以支持快速的“查找”、“插入”和“删除”操作。这些操作均具有较低的时间复杂度,因此,二叉搜索树经常被用于需要高效查找、插入和删除操作的场合。

3. 二叉搜索树的实现

3.1 节点的定义

从二叉搜索树的定义可以看出,每个节点包含一个键值,因此,我们需要一个节点的结构体。对于每个节点,我们需要记录其键值,以及其左右子节点的指针。

struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};

3.2 实现“插入”操作

插入操作是将一个新节点插入到二叉搜索树中。要插入新节点,我们需要遍历二叉搜索树,找到一个合适的位置,使得新节点的键值满足二叉搜索树的定义。

class BST {
public:
    TreeNode* insert(int val) {
        if (root_ == nullptr) {
            root_ = new TreeNode(val);
            return root_;
        }
        TreeNode* p = root_;
        while (true) {
            if (val < p->val) {
                if (p->left == nullptr) {
                    p->left = new TreeNode(val);
                    return p->left;
                }
                p = p->left;
            } else {
                if (p->right == nullptr) {
                    p->right = new TreeNode(val);
                    return p->right;
                }
                p = p->right;
            }
        }
    }

private:
    TreeNode* root_ = nullptr;
};

在这段代码中,我们使用指针变量p来遍历二叉搜索树,找到合适的插入位置。如果val小于p的键值,则将p的指针移动到其左子节点,否则将其指针移动到右子节点,直到找到需要插入节点的位置。如果根节点为空,则直接在根节点处插入新节点。

3.3 实现“查找”操作

查找操作可以在二叉搜索树中查找一个键值是否存在。这也需要遍历二叉搜索树,查找对应的节点。

class BST {
public:
    bool search(int val) {
        TreeNode* p = root_;
        while (p != nullptr) {
            if (p->val == val)
                return true;
            if (p->val > val)
                p = p->left;
            else
                p = p->right;
        }
        return false;
    }

private:
    TreeNode* root_ = nullptr;
};

在这段代码中,我们使用指针变量p来遍历二叉搜索树,找到对应的节点。如果当前节点的键值等于目标值,则返回true;否则,根据键值的大小关系,将p的指针移动到左右子节点。

3.4 实现“删除”操作

删除操作可以将二叉搜索树中的某个节点删除。删除节点有三种情况:对应节点没有子节点、对应节点只有一个子节点、对应节点有两个子节点。我们需要针对这三种情况来进行删除操作。

class BST {
public:
    void deleteNode(int val) {
        TreeNode* cur = root_;
        TreeNode* pre = nullptr;
        while (cur != nullptr && cur->val != val) {
            pre = cur;
            if (cur->val < val)
                cur = cur->right;
            else
                cur = cur->left;
        }
        if (cur == nullptr)
            return;
        if (cur->left != nullptr && cur->right != nullptr) {
            TreeNode* t = cur->right;
            while (t->left != nullptr)
                t = t->left;
            cur->val = t->val;
            cur = t;
            pre = cur->right;
        }
        TreeNode* c;
        if (cur->left != nullptr)
            c = cur->left;
        else
            c = cur->right;
        if (cur == root_)
            root_ = c;
        else if (pre->left == cur)
            pre->left = c;
        else
            pre->right = c;
        delete cur;
    }

private:
    TreeNode* root_ = nullptr;
};

在这段代码中,我们使用指针变量curpre来遍历二叉搜索树,找到对应的节点。如果当前节点有两个子节点,则用其右子树的最左节点来替换当前节点,并将删除操作转换为删除该最左节点的操作。如果当前节点只有一个子节点,则将其子节点指针赋值给当前节点的父节点。如果当前节点没有子节点,则直接将其删除。

4. 示例

4.1 示例一:从数组构建二叉搜索树

int main() {
    vector<int> nums = {9, 4, 15, 12, 20};
    BST bst;
    for (int num : nums)
        bst.insert(num);
    cout << bst.search(12) << endl; // 1
    cout << bst.search(19) << endl; // 0
    bst.deleteNode(15);
    cout << bst.search(15) << endl; // 0
    return 0;
}

在这个示例中,我们使用BST类来实现二叉搜索树的操作。首先将数组nums插入到二叉搜索树中,然后查找数值为12的节点是否存在,结果为1;查找数值为19的节点是否存在,结果为0。最后删除键值为15的节点,并再次查找,结果为0。

4.2 示例二:从文件构建二叉搜索树

int main() {
    ifstream infile;
    infile.open("data.txt");
    if (!infile) {
        cout << "Error: file not found" << endl;
        return 0;
    }
    BST bst;
    int num;
    while (infile >> num)
        bst.insert(num);
    infile.close();
    cout << bst.search(7) << endl; // 1
    return 0;
}

在这个示例中,我们从文件中读取数字,然后插入到二叉搜索树中。在本例中,数据存储在data.txt文件中。最后查找数值为7的节点是否存在,结果为1。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++数据结构之二叉搜索树的实现详解 - Python技术站

(0)
上一篇 2023年5月17日
下一篇 2023年5月17日

相关文章

  • redis数据结构之intset的实例详解

    Redis数据结构之intset的实例详解 介绍 Redis是一个高性能的key-value存储系统,支持多种数据结构。其中,intset是Redis内置的一种特殊的数据结构,它可以高效地存储整型数据。 本篇文章将介绍intset的基本特性、底层实现以及相关用例,以便读者能够更好地了解该数据结构在Redis中的应用。 intset的基本特性 intset是一…

    数据结构 2023年5月17日
    00
  • Java数据结构之链表实现(单向、双向链表及链表反转)

    Java数据结构之链表实现 链表基础概念 链表是一种数据结构,它由一系列节点(Node)组成,每个节点包含两个部分,一个是数据域(data),一个是指针域(next)。数据域存储数据信息,指针域指向下一个节点。 链表的种类很多,比如单向链表、双向链表、循环链表等等。 单向链表:链表的每个节点只有一个指针域,指向下一个节点。 双向链表:链表的每个节点有两个指针…

    数据结构 2023年5月17日
    00
  • GPS北斗卫星时间同步系统助力电力自动化网络系统

    GPS北斗卫星时间同步系统助力电力自动化网络系统 GPS北斗卫星时间同步系统助力电力自动化网络系统 京准电子官微——ahjzsz 前言 近几年来,随着电力自动化水平的提高,在电力中计算机监控系统、微机保护装置、微机故障录波装置以及各类数据管理机得到了广泛的应用,而这些自动装置的配合工作需要有一个精确统一的时间。当电力系统发生故障时,既可实现全站各系统在统一时…

    算法与数据结构 2023年5月8日
    00
  • 快速排序(整数)的C语言代码和JAVA代码

    一、问题描述 我们目前有一些数据,这些数据都是整数,然后我们现在需要做的就是把这些数据按照小到大排一下,然后输出出来。 二、问题的解决办法 首先确认一下分界点,我们常见的分界点是第一个点,第二个点,中间的一个点; 然后我们调整一下范围,也就说所有小于等于某个点的值在左半边,大于等于某个点的值在右半边。 递归处理左右两端。 案例如下: 我们首先手头有一些数据,…

    算法与数据结构 2023年4月18日
    00
  • C语言中单链表的基本操作指南(增删改查)

    C语言中单链表的基本操作指南如下: 单链表 单链表是一种线性结构,具有链式存储的特点,即用指针相连的方式存储数据。单链表的每个节点包含一个数据域和一个指向下一个节点的指针域。单链表与数组相比,其插入和删除操作效率较高,但是查找效率较低。 在C语言中,可以使用结构体和指针实现单链表。如下所示,Node结构体表示单链表中的一个节点,包含一个数据成员和一个指向下一…

    数据结构 2023年5月17日
    00
  • Go语言数据结构之插入排序示例详解

    Go语言数据结构之插入排序示例详解 什么是插入排序? 插入排序是一种简单直观的排序方法,其基本思想是将一个待排序的序列分成已排序和未排序两部分,从未排序的部分中选择一个元素插入到已排序部分的合适位置,直到所有元素都被插入到已排序部分为止。 插入排序示例 示例1 我们来看一个数字序列的插入排序示例: package main import "fmt&…

    数据结构 2023年5月17日
    00
  • JavaScript数据结构和算法之二叉树详解

    JavaScript数据结构和算法之二叉树详解 什么是二叉树? 二叉树是一种树形结构,其中每个节点最多有两个子节点:左子节点和右子节点。每个节点都是一个对象,包括属性和方法。节点的属性可能包括值,左节点和右节点。节点的方法可能包括插入和删除。 二叉树的应用场景 二叉树的常用场景包括: 排序算法(二叉排序树); 表达式求值; 线段树; 图形图像学; 数据压缩算…

    数据结构 2023年5月17日
    00
  • MySQL底层数据结构选用B+树的原因

    MySQL底层数据结构选用B+树的原因主要是因为B+树具有以下优点: 能够快速查找B+树的查找速度非常快,时间复杂度为O(log n),在海量数据的环境中,能够快速定位目标数据。因为B+树每次查找只需要遍历树高度的次数,即使数据量很大,树的高度也很小。 能够高效地进行增删改操作B+树的平衡性能够保证树的高度非常小,大部分操作只需要遍历树的高度,而不是整颗树,…

    数据结构 2023年5月17日
    00
合作推广
合作推广
分享本页
返回顶部