数据结构--C++实现二叉查找树

本文详细介绍了二叉搜索树的数据结构实现,包括插入、查找和删除节点的算法,并通过C++代码示例展示了如何构建和操作二叉搜索树。文章深入解析了树的平衡与调整策略,以及中序遍历的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 直接上代码,很多解释我都再代码里面有说明,如果有什么问题欢迎交流

#include <iostream>
#include <string>
#include <utility>
#include <algorithm>

using namespace std;

struct Node
{
    int key;
    Node * left;
    Node * right;
    Node(int key)//结构体的构造函数,结构体默认都是public,而class属性默认private
    {
        this->key = key;
        this->left = this->right = nullptr;
    }
};

class BST_HWQ
{
private:
    Node * header;
private:
    void destroy(Node * node);
    Node * insert_real(int key, Node *& node);
    Node *& find_real(int key, Node *& node);
    void in_order(Node * node);
public:
    BST_HWQ();
    ~BST_HWQ();
    Node * insert(int key);
    Node * find(int key);
    void erase(int key);
    void print();
};

BST_HWQ::BST_HWQ()  //构造函数
{
    header = new Node(0);
}

BST_HWQ::~BST_HWQ()  //析构函数
{
    destroy(header->left);
    delete header;
    header = nullptr;
}

void BST_HWQ::destroy(Node * node)
{
    if (node == nullptr)
        return;
    destroy(node->left);//递归删除节点
    destroy(node->right);
    delete node;  //释放指针指向的内存,指针本身变成野指针,要赋值nullptr
}

Node * BST_HWQ::insert_real(int key, Node *& node)//返回Node型指针,参数为插入数值和Node*类型的引用变量
{
    if (node == nullptr)
        return node = new Node(key);

    if (key < node->key)  //递归的找位置然后插入
        return insert_real(key, node->left);
    else if (key > node->key)
        return insert_real(key, node->right);
    else
        return nullptr;      //相等不插入
}

Node *& BST_HWQ::find_real(int key, Node *& node)//递归查找元素
{
    if (node == nullptr)
        return node;

    if (key < node->key)
        return find_real(key, node->left);
    else if (key > node->key)
        return find_real(key, node->right);
    else
        return node;
}

void BST_HWQ::in_order(Node * node) //中序遍历二叉树
{
    if (node == nullptr)
        return;

    in_order(node->left);
    cout << node->key << " ";
    in_order(node->right);
}

Node * BST_HWQ::insert(int key)//对外调用接口,在内部调用insert_real
{
    return insert_real(key, header->left);
}

Node * BST_HWQ::find(int key)
{
    return find_real(key, header->left);
}

void BST_HWQ::erase(int key)     //要先找到值所在的节点,然后删除之后要对其子节点进行调整
{
    Node *& p = find_real(key, header->left);//Node*类型的引用,操作引用变量相当于操作"实际"变量
    if (p)
    {
        Node * t = p;    //创建一个临时指针指向要删除的节点
        if (t->left && t->right)
        {
            // 找到 t 的后继结点
            Node * y = t;      //y用于保存当前节点的父亲节点
            Node * x = t->right;
            while (x->left)
            {
                y = x;
                x = x->left;
            }

            // 将后继结点的右子树接上它的父亲
            if (y == t)
                y->right = x->right;//大家如果清楚.和->的含义的话,下面的代码就不会觉得矛盾了
            else                                 //->得到的是那个东西的地址,.得到的是那个东西的值
                y->left = x->right;

            // 用后继结点替换要删除的结点 t
            p = x;
            x->left = t->left;
            x->right = t->right;
        }
        else
            p = t->left ? t->left : t->right;   //判断左孩子是否为真
        
        delete t;
    }
}

void BST_HWQ::print()
{
    in_order(header->left);
    cout << endl;
}

int main()
{
    BST_HWQ bst_hwq;

    // test "insert"
    bst_hwq.insert(7);//第一个插入了什么根就决定了
    bst_hwq.insert(2);
    bst_hwq.insert(1); bst_hwq.insert(1);//不会插入相同的
    bst_hwq.insert(5);
    bst_hwq.insert(3);
    bst_hwq.insert(6);
    bst_hwq.insert(4);
    bst_hwq.insert(9);
    bst_hwq.insert(8);
    bst_hwq.insert(11); bst_hwq.insert(11);
    bst_hwq.insert(10);
    bst_hwq.insert(12);
    bst_hwq.print(); // 1 2 3 4 5 6 7 8 9 10 11 12//二叉查找的中序遍历结果就是排序结果

    // test "find"
    Node * p = nullptr;
    cout << ((p = bst_hwq.find(2)) ? p->key : -1) << endl;   //  2      判断p是否为真
    cout << ((p = bst_hwq.find(100)) ? p->key : -1) << endl; // -1

    // test "erase"
    bst_hwq.erase(2);
    bst_hwq.print(); // 1 3 4 5 6 7 8 9 10 11 12
    bst_hwq.erase(10);
    bst_hwq.erase(9);
    bst_hwq.print(); // 1 3 4 5 6 7 8 11 12

    return 0;
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值