Skip to content

Repository files navigation

非侵入式的RAII风格的泛型二叉树实现,旨在通过合理的封装实现二叉树子树操作无需内存管理,且不泄露。

目标

  • 和C++标准库保持风格一致
  • 零开销原则
  • 支持分配器语义
  • head-only

非目标

  • 这不是一个序列容器库,因此不提供迭代器功能,不假定遍历顺序
  • 这不是平衡树或者二叉搜索树的公共基座,是普通的二叉树操作库
  • 当前要求C++版本是C++23,可能考虑前移到C++20,但是不会进一步向前兼容。

主要代码架构

主要发布件为binary_tree.hparent_aware_binary_tree.h,这两个头文件依赖union_data.h,将文件直接放在头文件目录即可使用,无需配置构建选项。两个库对应设施的文档可以在binary_tree_readme和parent_aware_binary_tree_readme目录下查阅。

另外,为了验证二叉树库的封装能力,本仓库实现了基于红黑树、AVL、SBT、FHQ treap四种平衡树搭建的旨在提供和std::set同样接口的类模板作为POC项目。如果有兴趣继续完善或者进行测试可以参考下面的包含关系进行引入。

rb_set.h,avl_set.h,sbt_set.h,fhq_treap_set.h为最终头文件,也是include的目标,它们依赖三叉链法二叉树基座库parent_aware_binary_tree.h,公共迭代器实现set_common.h以及分配器元信息注入机制cookie_allocator.h。这些头文件都是自包含的。

性能

可以自行运行benchmark_perf.cpp试一试,用以测试使用parent_aware_binary_tree搭建的红黑树的性能。

开发者本机跑出来的结果如下,其中比率是耗时比率,数字越大说明自实现相对std::set比性能越好。

N=500,000 × 50 轮,双编译器对比:

测试	            MSVC 比率	    MinGW 比率	    MSVC rb	    MinGW rb
insert_random	    0.93x	        0.92x	        382.6ms	    262.5ms
insert_sorted	    0.74x	        1.12x	        70.8ms	    39.8ms
find	            0.98x	        0.98x	        368.3ms	    377.1ms
erase	            1.22x	        1.01x	        174.9ms	    182.7ms
iteration	        0.69x	        0.98x	        70.9ms	    71.0ms
mixed	            0.94x	        0.90x	        155.8ms	    149.0ms

快速开始

#include <print>
#include "binary_tree.h"

struct simple_binary_tree_node
{
    simple_binary_tree_node* left{};
    simple_binary_tree_node* right{};
    int val;
    std::pair<simple_binary_tree_node*, simple_binary_tree_node*> children()const noexcept
    {
        return { left,right };
    }
};

int main()
{
    simple_binary_tree_node tree[]{
                           {tree + 1,tree + 2,1},
    //                      |
    //              ---------------------
    //              |                   |
                   {{},{},2},          {{tree + 3},{tree + 4},3},
    //                                  |
    //                          -----------------
    //                          |               |
                               { {},{},4 },    {{},{},5}
    };
    Yc::binary_tree<int> b{ &simple_binary_tree_node::val,&simple_binary_tree_node::children,&tree[0] };
    Yc::binary_tree<int>::edge_proxy p = b.root();
    p.go_right().go_left();
    std::print("b的右孩子的左孩子是{}", *p);
}

输出

b的右孩子的左孩子是4

About

非侵入式的二叉树实现

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages