获取当前被选中的树节点ztree_第9篇: C++数据结构 二叉搜索树(前)

本文介绍了二叉搜索树(BST)的基本概念、性质及类接口设计。BST中,左子树节点值小于当前节点,右子树节点值大于当前节点,且不允许重复值。通过递归算法计算BST的高度,插入和查找操作。此外,文章讨论了BST在不同形态下的高度计算,并提供了构造函数和析构函数的实现。
摘要由CSDN通过智能技术生成

二叉查找树和前面所过的二叉堆在实现存在很大区别,在二叉搜索树(Binary Search Tree或者简称BST)中,任意节点的左子树中的所有节点的值要小于其右子树中的所有节点的值

二叉搜索树的性质:

  • 任一当前节点的左子树包含的节点值小于当前节点。
  • 任一当前节点的右子树包含的节点值大于当前节点。
  • 任意两个节点不能有重复的值。(这个性质非常重要,它使得BST可以构架另外一个数据结构Set,Set中每个元素都是唯一的。)
  • 除了叶子节点外,任意节点左子树和右子树也必须满足BST性质。

二叉搜索树的上述属性提供了节点值之间的排序关系,从而可以快速完成搜索、最小和最大等操作。但事实上,BST构建的排序逻辑事实上属于分治排序思想的其中一种,为什么这么说:

  • 也就是说从BST的根节点为轴(Pivot)。左半分区就是根节点左子树,右半分区是根节点的右子树,这个操作我们叫分区(Partition).
  • 分治排序的整个算法需要依次对左子数或右子树逐层递归执行。

但BST的不强制任意一个路径的所有节点的值都严格依照降序或升序排列,这有异于分治排序算法的。例如下图的完整二叉树,同时也是一个BST,我们看看具体的例子{32、16、11、23}和{32,16,11,31},这两条路径上的节点都不完全排序。

但我们换个角度去思考一下,如果我们设定两个参照条件。

  • 条件1:锁定第h层对应的根节点。
  • 条件2:限定每层遍历的方向:要么是一路按左节点遍历,要么一路按右节点遍历。

那么有趣的事情发生了

例如我以值为32的节点为根,一路left遍历,依次是降序排列的:

例如我以值为16的节点为根,一路right遍历,依次是升序排列的:

例如我以值为32的节点为根,一路right遍历,依次是升序排列的:

40c0fd2c395401a8dfff492e7f55e325.png

这里可以总结出BST的另外一些特性。

当明确第h层的参照节点为根

  • 性质1:往左节点方向逐层遍历到叶子节点
    ,那么得到
    的序列是一个降序的线性表。
  • 性质2:往右节点方向逐层遍历到叶子节点
    ,那么得到
    的序列是一个升序的线性表

BST的类接口设计

我们知道BST构成的基本要素是节点,因此请查看如下BSNode类定义的代码清单

#ifndef __BSTREE_HH__
#define __BSTREE_HH__
#include <iostream>

//BSTree类模板声明
template<class T>
class BSTree;

//BST迭代器类模板声明
template<class T>
class BSTreeIterator;

template<class T>
class BNode{
    
    friend class BSTree<T>;
private:
    BNode<T>* d_parent; //父节点
    BNode<T>* d_left;   //左子节点
    BNode<T>* d_right;  //右子节点
    T d_data;           //数据域

public:
    BNode(T val){
    
        d_data=val;
        d_parent=nullptr;
        d_left=nullptr;
        d_right=nullptr;
    }

    ~BNode(){
    
        d_parent=nullptr;
        d_left=nullptr;
        d_right=nullptr;
    }
};

BST容器的类接口

在前面的ArrayList、LinkedList、Queue篇章,笔者多次强调过“容器”这个概念,这也是C++的std代码库组织内置所有数据结构的通用的编程风格。BST容器封装了BST的根、以及增、删、改、查等API的核心算法。

template<class T>
class BSTree{
    
private:
    BNode<T>* d_root; //整个树的根
    int d_height;    //当前树的高度
    int d_size;      //当前元素的高度

    //内部递归插入算法
    BNode<T>* insertRcu(BNode<T>*,T);

    void clear(BN
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值