封装红黑树代码

Visual Studio Git 使用指南 Visual Studio 2022深度集成了Git功能,提供了直观的图形界面管理源代码。本文详细介绍了VS中Git的使用方法:从环境准备、克隆/创建仓库开始,重点讲解了"Git更改"窗口的日常操作,包括查看修改、暂存文件、提交推送等。同时涵盖了分支管理、查看历史、解决冲突等核心功能,以及储藏、重置等高级操作。文章还提供了实用技巧,如提交规范、频繁提交等最佳实践。VS的Git集成覆盖了日常开发需求,图形界面与命令行可互补使用,适合各层次开发者高效管理代码版本。 阅读详情

首先展示测试结果

/*************************************************************************
    > File Name: test_rbtree_api.cc
    > Author: hsz
    > Brief:
    > Created Time: Thu 24 Nov 2022 11:08:34 AM CST
 ************************************************************************/

#include <utils/rbtree_api.h>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>

using namespace std;

struct RBData {
    rb_node rbNode;
    int data;
};

rb_root root;

#define rbdata_entry(node) rb_entry(node, RBData, rbNode)

void free_node(rb_node *node)
{
    RBData *data = rbdata_entry(node);
    printf("%s() free(%p) data = %d\n", __func__, data, data->data);
    delete data;
}

bool processData(rb_node *node)
{
    RBData *data = rbdata_entry(node);
    printf("\t%s() data = %d\n", __func__, data->data);
    if (data->data == 4) {
        free_node(rbtree_erase_node(&root, node)); // 测试在遍历时删除节点是否产生异常
    }
    return false;
}

int compare_key(rb_node *node, const void *seed)
{
    int key = *static_cast<const int *>(seed);
    RBData *data = rbdata_entry(node);
    if (data->data < key) {
        return -1;
    }
    if (data->data > key) {
        return 1;
    }

    return 0;
}

int compare_node(rb_node *left, rb_node *right)
{
    RBData *l = rbdata_entry(left);
    RBData *r = rbdata_entry(right);

    if (l->data < r->data) {
        return -1;
    }
    if (l->data > r->data) {
        return 1;
    }

    return 0;
}

int main(int argc, char **argv)
{
    rbtree_init(&root);
    rbtree_foreach(&root, processData);

    printf("\n--->rbtree size = %zu\n", rbtree_size(&root));

    printf("insert to(%p) 1, 3, 5\n", &root);
    RBData *newNode = new RBData;
    newNode->data = 1;
    rbtree_insert(&root, &newNode->rbNode, compare_node);

    newNode = new RBData;
    newNode->data = 3;
    rbtree_insert(&root, &newNode->rbNode, compare_node);

    newNode = new RBData;
    newNode->data = 5;
    rbtree_insert(&root, &newNode->rbNode, compare_node);

    printf("\nforeach rbtree(%p)\n", &root);
    rbtree_foreach(&root, processData);

    printf("\ninsert to(%p) 2, 4\n", &root);
    newNode = new RBData;
    newNode->data = 2;
    rbtree_insert(&root, &newNode->rbNode, compare_node);

    newNode = new RBData;
    newNode->data = 4;
    rbtree_insert(&root, &newNode->rbNode, compare_node);

    printf("\n--->rbtree size = %zu\n", rbtree_size(&root));

    printf("\nforeach rbtree(%p) and will erase data 4\n", &root);
    rbtree_foreach(&root, processData);

    printf("\n--->rbtree size = %zu\n", rbtree_size(&root));

    int num = 3;
    printf("\nerase %d from rbtree(%p)\n", num, &root);
    rbtree_erase(&root, &num, compare_key);

    printf("\nforeach rbtree(%p)\n", &root);
    rbtree_foreach(&root, processData);

    printf("\nclear rbtree\n");
    rbtree_clear(&root, free_node);
    printf("\n--->rbtree size = %zu\n", rbtree_size(&root));
    return 0;
}

在这里插入图片描述

目前是以C接口和回调形式给出,后续会封装成类和iterator,或将参考QMap的封装形式

完整代码

/*************************************************************************
    > File Name: rbtree_base.h
    > Author: hsz
    > Brief: linux rbtree source code
    > Created Time: Sat 11 Dec 2021 01:26:52 PM CST
 ************************************************************************/

#ifndef __RBTREE_H__
#define __RBTREE_H__

struct rb_node
{
    struct rb_node *rb_parent;
    struct rb_node *rb_right;
    struct rb_node *rb_left;
    char            rb_color;
#define RB_RED      0
#define RB_BLACK    1
};

struct rb_root
{
    struct rb_node *rb_node;
};

#define RB_ROOT (struct rb_root){ (struct rb_node *)0, }
#define rb_entry(ptr, type, member) \
    ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))

#ifdef __cplusplus
extern "C"
{
#endif

void rb_insert_color(struct rb_node *node, struct rb_root *root);
void rb_erase(struct rb_node *node, struct rb_root *root);

/* Find logical next and previous nodes in a tree */
struct rb_node *rb_next(struct rb_node *);
struct rb_node *rb_prev(struct rb_node *);
struct rb_node *rb_first(struct rb_root *);
struct rb_node *rb_last(struct rb_root *);

/* Fast replacement of a single node without remove/rebalance/add/rebalance */
void rb_replace_node(struct rb_node *victim, struct rb_node *newnode,
                struct rb_root *root);

#ifdef __cplusplus
}
#endif

static inline void rb_link_node(struct rb_node *node, struct rb_node *parent,
                struct rb_node **link)
{
    node->rb_parent = parent;
    node->rb_color = RB_RED;
    node->rb_left = node->rb_right = (struct rb_node *)0;
    *link = node;
}

#endif // __RBTREE_H__
/*************************************************************************
    > File Name: rbtree_base.cpp
    > Author: hsz
    > Brief:
    > Created Time: Sun 12 Dec 2021 11:11:06 PM CST
 ************************************************************************/

#include "rbtree_base.h"

static void __rb_rotate_left(struct rb_node *node, struct rb_root *root)
{
    struct rb_node *right = node->rb_right;

    if ((node->rb_right = right->rb_left))
        right->rb_left->rb_parent = node;
    right->rb_left = node;

    if ((right->rb_parent = node->rb_parent))
    {
        if (node == node->rb_parent->rb_left)
            node->rb_parent->rb_left = right;
        else
            node->rb_parent->rb_right = right;
    }
    else
        root->rb_node = right;
    node->rb_parent = right;
}

static void __rb_rotate_right(struct rb_node *node, struct rb_root *root)
{
    struct rb_node *left = node->rb_left;

    if ((node->rb_left = left->rb_right))
        left->rb_right->rb_parent = node;
    left->rb_right = node;

    if ((left->rb_parent = node->rb_parent))
    {
        if (node == node->rb_parent->rb_right)
            node->rb_parent->rb_right = left;
        else
            node->rb_parent->rb_left = left;
    }
    else
        root->rb_node = left;
    node->rb_parent = left;
}

void rb_insert_color(struct rb_node *node, struct rb_root *root)
{
    struct rb_node *parent, *gparent;

    while ((parent = node->rb_parent) && parent->rb_color == RB_RED)
    {
        gparent = parent->rb_parent;

        if (parent == gparent->rb_left)
        {
            {
                register struct rb_node *uncle = gparent->rb_right;
                if (uncle && uncle->rb_color == RB_RED)
                {
                    uncle->rb_color = RB_BLACK;
                    parent->rb_color = RB_BLACK;
                    gparent->rb_color = RB_RED;
                    node = gparent;
                    continue;
                }
            }

            if (parent->rb_right == node)
            {
                register struct rb_node *tmp;
                __rb_rotate_left(parent, root);
                tmp = parent;
                parent = node;
                node = tmp;
            }

            parent->rb_color = RB_BLACK;
            gparent->rb_color = RB_RED;
            __rb_rotate_right(gparent, root);
        } else {
            {
                register struct rb_node *uncle = gparent->rb_left;
                if (uncle && uncle->rb_color == RB_RED)
                {
                    uncle->rb_color = RB_BLACK;
                    parent->rb_color = RB_BLACK;
                    gparent->rb_color = RB_RED;
                    node = gparent;
                    continue;
                }
            }

            if (parent->rb_left == node)
            {
                register struct rb_node *tmp;
                __rb_rotate_right(parent, root);
                tmp = parent;
                parent = node;
                node = tmp;
            }

            parent->rb_color = RB_BLACK;
            gparent->rb_color = RB_RED;
            __rb_rotate_left(gparent, root);
        }
    }

    root->rb_node->rb_color = RB_BLACK;
}

static void __rb_erase_color(struct rb_node *node, struct rb_node *parent,
                 struct rb_root *root)
{
    struct rb_node *other;

    while ((!node || node->rb_color == RB_BLACK) && node != root->rb_node)
    {
        if (parent->rb_left == node)
        {
            other = parent->rb_right;
            if (other->rb_color == RB_RED)
            {
                other->rb_color = RB_BLACK;
                parent->rb_color = RB_RED;
                __rb_rotate_left(parent, root);
                other = parent->rb_right;
            }
            if ((!other->rb_left ||
                 other->rb_left->rb_color == RB_BLACK)
                && (!other->rb_right ||
                other->rb_right->rb_color == RB_BLACK))
            {
                other->rb_color = RB_RED;
                node = parent;
                parent = node->rb_parent;
            }
            else
            {
                if (!other->rb_right ||
                    other->rb_right->rb_color == RB_BLACK)
                {
                    register struct rb_node *o_left;
                    if ((o_left = other->rb_left))
                        o_left->rb_color = RB_BLACK;
                    other->rb_color = RB_RED;
                    __rb_rotate_right(other, root);
                    other = parent->rb_right;
                }
                other->rb_color = parent->rb_color;
                parent->rb_color = RB_BLACK;
                if (other->rb_right)
                    other->rb_right->rb_color = RB_BLACK;
                __rb_rotate_left(parent, root);
                node = root->rb_node;
                break;
            }
        }
        else
        {
            other = parent->rb_left;
            if (other->rb_color == RB_RED)
            {
                other->rb_color = RB_BLACK;
                parent->rb_color = RB_RED;
                __rb_rotate_right(parent, root);
                other = parent->rb_left;
            }
            if ((!other->rb_left ||
                 other->rb_left->rb_color == RB_BLACK)
                && (!other->rb_right ||
                other->rb_right->rb_color == RB_BLACK))
            {
                other->rb_color = RB_RED;
                node = parent;
                parent = node->rb_parent;
            }
            else
            {
                if (!other->rb_left ||
                    other->rb_left->rb_color == RB_BLACK)
                {
                    register struct rb_node *o_right;
                    if ((o_right = other->rb_right))
                        o_right->rb_color = RB_BLACK;
                    other->rb_color = RB_RED;
                    __rb_rotate_left(other, root);
                    other = parent->rb_left;
                }
                other->rb_color = parent->rb_color;
                parent->rb_color = RB_BLACK;
                if (other->rb_left)
                    other->rb_left->rb_color = RB_BLACK;
                __rb_rotate_right(parent, root);
                node = root->rb_node;
                break;
            }
        }
    }
    if (node)
        node->rb_color = RB_BLACK;
}

void rb_erase(struct rb_node *node, struct rb_root *root)
{
    struct rb_node *child, *parent;
    int color;

    if (!node->rb_left)
        child = node->rb_right;
    else if (!node->rb_right)
        child = node->rb_left;
    else
    {
        struct rb_node *old = node, *left;

        node = node->rb_right;
        while ((left = node->rb_left))
            node = left;
        child = node->rb_right;
        parent = node->rb_parent;
        color = node->rb_color;

        if (child)
            child->rb_parent = parent;
        if (parent)
        {
            if (parent->rb_left == node)
                parent->rb_left = child;
            else
                parent->rb_right = child;
        }
        else
            root->rb_node = child;

        if (node->rb_parent == old)
            parent = node;
        node->rb_parent = old->rb_parent;
        node->rb_color = old->rb_color;
        node->rb_right = old->rb_right;
        node->rb_left = old->rb_left;

        if (old->rb_parent)
        {
            if (old->rb_parent->rb_left == old)
                old->rb_parent->rb_left = node;
            else
                old->rb_parent->rb_right = node;
        } else
            root->rb_node = node;

        old->rb_left->rb_parent = node;
        if (old->rb_right)
            old->rb_right->rb_parent = node;
        goto color;
    }

    parent = node->rb_parent;
    color = node->rb_color;

    if (child)
        child->rb_parent = parent;
    if (parent)
    {
        if (parent->rb_left == node)
            parent->rb_left = child;
        else
            parent->rb_right = child;
    }
    else
        root->rb_node = child;

 color:
    if (color == RB_BLACK)
        __rb_erase_color(child, parent, root);
}

/*
 * This function returns the first node (in sort order) of the tree.
 */
struct rb_node *rb_first(struct rb_root *root)
{
    struct rb_node *n;

    n = root->rb_node;
    if (!n)
        return (struct rb_node *)0;
    while (n->rb_left)
        n = n->rb_left;
    return n;
}

struct rb_node *rb_last(struct rb_root *root)
{
    struct rb_node *n;

    n = root->rb_node;
    if (!n)
        return (struct rb_node *)0;
    while (n->rb_right)
        n = n->rb_right;
    return n;
}

struct rb_node *rb_next(struct rb_node *node)
{
    /* If we have a right-hand child, go down and then left as far
       as we can. */
    if (node->rb_right) {
        node = node->rb_right;
        while (node->rb_left)
            node = node->rb_left;
        return node;
    }

    /* No right-hand children.  Everything down and left is
       smaller than us, so any 'next' node must be in the general
       direction of our parent. Go up the tree; any time the
       ancestor is a right-hand child of its parent, keep going
       up. First time it's a left-hand child of its parent, said
       parent is our 'next' node. */
    while (node->rb_parent && node == node->rb_parent->rb_right)
        node = node->rb_parent;

    return node->rb_parent;
}

struct rb_node *rb_prev(struct rb_node *node)
{
    /* If we have a left-hand child, go down and then right as far
       as we can. */
    if (node->rb_left) {
        node = node->rb_left;
        while (node->rb_right)
            node = node->rb_right;
        return node;
    }

    /* No left-hand children. Go up till we find an ancestor which
       is a right-hand child of its parent */
    while (node->rb_parent && node == node->rb_parent->rb_left)
        node = node->rb_parent;

    return node->rb_parent;
}

void rb_replace_node(struct rb_node *victim, struct rb_node *newnode,
             struct rb_root *root)
{
    struct rb_node *parent = victim->rb_parent;

    /* Set the surrounding nodes to point to the replacement */
    if (parent) {
        if (victim == parent->rb_left)
            parent->rb_left = newnode;
        else
            parent->rb_right = newnode;
    } else {
        root->rb_node = newnode;
    }
    if (victim->rb_left)
        victim->rb_left->rb_parent = newnode;
    if (victim->rb_right)
        victim->rb_right->rb_parent = newnode;

    /* Copy the pointers/colour from the victim to the replacement */
    *newnode = *victim;
}
/*************************************************************************
    > File Name: rbtree_api.h
    > Author: hsz
    > Brief:
    > Created Time: Wed 23 Nov 2022 11:10:12 AM CST
 ************************************************************************/

#ifndef __UTILS_RBTREE_API_H__
#define __UTILS_RBTREE_API_H__

#include "rbtree_base.h"
#include "utils.h"

EXTERN_C_BEGIN

void rbtree_init(rb_root *root);
void rbtree_clear(rb_root *root, void (*free_node_cb)(rb_node *));

/**
 * @brief 将node插入到红黑树root
 * 
 * @param root 红黑树
 * @param node 红黑树节点
 * @param compare_callback 比较回调。返回0表示相等,返回1往右子树放,返回-1往左子树放。
 * @return rb_node* 成功返回插入的节点地址,失败返回nullptr
 */
rb_node *rbtree_insert(rb_root *root, rb_node *newNode, int (*compare_callback)(rb_node *, rb_node *));

/**
 * @brief 从红黑树中删除等于seed的节点,但不释放此节点内存
 * 
 * @param root 红黑树根节点
 * @param seed 种子
 * @param equal_callback 判断相等回调
 * @return rb_node* 成功返回删除的节点,失败返回nullptr
 */
rb_node *rbtree_erase(rb_root *root, const void *seed, int (*compare_callback)(rb_node *, const void *));

rb_node *rbtree_erase_node(rb_root *root, rb_node *node);

/**
 * @brief 对红黑树进行有序遍历(在遍历中删除是不安全的?)
 * 
 * @param root 红黑树根节点
 * @param data_callback 数据处理回调. 从循环中退出返回true,不退出返回false
 * @return true 遍历成功
 * @return false 遍历失败
 */
bool rbtree_foreach(rb_root *root, bool (*data_callback)(rb_node *node));

/**
 * @brief 从红黑树中查找与seed相等的节点
 * 
 * @param root 红黑树根节点
 * @param seed 种子数据
 * @param compare_callback 同rbtree_erase的compare_callback
 * @return rb_node* 返回查找到的节点,失败返回nullptr
 */
rb_node *rbtree_search(rb_root *root, const void *seed, int (*compare_callback)(rb_node *, const void *));

size_t rbtree_size(rb_root *root);

EXTERN_C_END

#endif // __UTILS_RBTREE_API_H__

/*************************************************************************
    > File Name: rbtree_api.cpp
    > Author: hsz
    > Brief:
    > Created Time: Wed 23 Nov 2022 03:56:21 PM CST
 ************************************************************************/

#include "rbtree_api.h"
#include <assert.h>

void rbtree_init(rb_root *root)
{
    if (root) {
        root->rb_node = nullptr;
    }
}

void rbtree_clear(rb_root *root, void (*free_node_cb)(rb_node *))
{
    if (root == nullptr) {
        return;
    }
    struct rb_node *node = nullptr;
    while (node = root->rb_node) {
        rb_erase(node, root);
        if (eular_likely(free_node_cb != nullptr)) {
            free_node_cb(node);
        }
    }
}

rb_node *rbtree_insert(rb_root *root, rb_node *newNode, int (*compare_callback)(rb_node *, rb_node *))
{
    if (root == nullptr || compare_callback == nullptr) {
        return nullptr;
    }

    struct rb_node **node = &(root->rb_node);
    struct rb_node *parent = nullptr;
    bool exists = false;
    int compareResult = 0;
    while (nullptr != (*node)) {
        parent = *node;
        compareResult = compare_callback(parent, newNode);
        if (compareResult < 0) { // parent < newNode
            node = &(*node)->rb_right;
        } else if (compareResult > 0) {
            node = &(*node)->rb_left;
        } else {
            exists = true;
            break;
        }
    }

    if (!exists) {
        rb_link_node(newNode, parent, node);
        rb_insert_color(newNode, root);
    }

    return exists ? nullptr : newNode;
}

rb_node *rbtree_erase(rb_root *root, const void *seed, int (*compare_callback)(rb_node *, const void *))
{
    if (root == nullptr || seed == nullptr || compare_callback == nullptr) {
        return nullptr;
    }

    struct rb_node *eraseNode = rbtree_search(root, seed, compare_callback);
    if (eraseNode != nullptr) {
        rb_erase(eraseNode, root);
    }

    return eraseNode;
}

bool isValidNode(rb_root *root, rb_node *node)
{
    assert(root && node);
    rb_node *parent = node;
    bool valid = false;
    while (parent) {
        if (parent == root->rb_node) {
            valid = true;
            break;
        }
        if (parent == parent->rb_parent) { // 需确定根节点的rb_parent是否为空,不为空则会死循环
            break;
        }
        parent = parent->rb_parent;
    }

    return valid;
}

rb_node *rbtree_erase_node(rb_root *root, rb_node *node)
{
    if (root == nullptr || node == nullptr) {
        return nullptr;
    }
    assert(isValidNode(root, node));
    
    rb_erase(node, root);
    return node;
}

bool rbtree_foreach(rb_root *root, bool (*data_callback)(rb_node *node))
{
    if (root == nullptr || data_callback == nullptr) {
        return false;
    }

    struct rb_node *begin = rb_first(root);
    struct rb_node *next = begin;
    struct rb_node *end = rb_last(root);

    if (begin == nullptr) { // no nodes
        return true;
    }

    // NOTE 由于遍历时是有序的,故保存next后,即使在回调中删除begin节点也不会导致循环出现问题,因为下一个节点本就应该是next
    while (begin != end) {
        next = rb_next(next);
        if (data_callback(begin)) {
            return true;
        }
        begin = next;
    }

    data_callback(end);
    return true;
}

rb_node *rbtree_search(rb_root *root, const void *seed, int (*compare_callback)(rb_node *, const void *))
{
    if (root == nullptr || compare_callback == nullptr) {
        return nullptr;
    }

    struct rb_node *curr = root->rb_node;
    bool exist = false;
    int compareResult = 0;
    while (curr) {
        compareResult = compare_callback(curr, seed);
        if (compareResult < 0) {
            curr = curr->rb_left;
        } else if (compareResult > 0) {
            curr = curr->rb_right;
        } else {
            exist = true;
            break;
        }
    }

    return exist ? curr : nullptr;
}

size_t rbtree_size(rb_root *root)
{
    if (root == nullptr) {
        return 0;
    }

    size_t count = 0;
    struct rb_node *begin = rb_first(root);
    struct rb_node *next = begin;
    struct rb_node *end = rb_last(root);

    if (begin == nullptr) {
        return 0;
    }

    while (begin != end) {
        next = rb_next(next);
        begin = next;
        ++count;
    }

    ++count; // for end
    return count;
}
MIMO-OFDM 通信-感知一体化(ISAC)中的联合优化与性能权衡 本文深入探讨了MIMO-OFDM技术在通信-感知一体化(ISAC)系统中的核心作用与挑战。文章分析了如何通过联合优化资源分配、波束成形与波形设计,在有限的频谱与硬件资源下,实现通信速率与感知精度之间的最佳平衡,并指出了工程实践中面临的同步、干扰等关键难题。 阅读详情

相关推荐

sdc时钟约束2——多驱动时钟

sdc 多驱动时钟 master_clock

qq_40411444的博客 5529

nginx源码学习2——扒、封装红黑树代码

说明: 1.nginx红黑树除了是个通用结构体,还是定时器实现的载体,进一步学习定时器代码需要了解红黑树用法; 2.nginx红黑树基本上只提供了一个初始化红黑树、增、删节点,查找最小节点四种操作,其实对nginx也够了; 3.nginx红黑树细节暴露比较多,节点要自己malloc自己构造,插入操作的第一步(旋转前)要自己实现(尽管各种实现的不同处都只是在key相同时提供比较大小的方法),节

liu3daniel的博客 407

比较几款国际主流的电子元器件及物料清单管理软件 – 工具汇总

Arenasolution 老牌的基于云计算物料清单管理软件,bom.com就是他们家的,10天免费试用,功能被分成4个不同的产品, 和传统ERP功能上有重叠,偏向于物流生产规划,一定程度可以取代ERP的生产规划模块,平均价格70美元/月/席位。网页客户端,不支持离线   SiliconExpert 曾经的老牌物料清单管理软件,后被Arrow 收购,14天免费试用,功能被分成4个不同的产品

u012062784的专栏 7235

C++红黑树封装set和map代码详解

我们都知道set和map的底层都是通过红黑树来实现的,前面讲解了红黑树的原理和代码,那么如何通过红黑树的代码封装实现set和map呢。

2401_84541745的博客 744

M2DGR数据集在一些SLAM框架上的配置与运行:ORB-SLAM系列、VINS-Mono、LOAM系列、FAST-LIO系列、hdl_graph_slam

为了说明以上这些SLAM框架的测试与数据集适配,以M2DGR数据集为例进行各自的配置与运行,方便我以后适配自己的数据集,运行的SLAM框架包括:ORB-SLAM2、ORB-SLAM3、VINS-Mono、A-LOAM、LeGO-LOAM、LIO-SAM、LVI-SAM、FAST-LIO2、FAST-LIVO、Faster-LIO、hdl_graph_slam。实验基于Ubuntu20.04,其中ORB、VINS-Mono、和LOAM系列的安装参考我以前的博客,有详细的安装方法,其他的框架在后面会简单介绍一下

zardforever123的博客 1万+

NE555构成多谐振荡器及三角波、正弦波的生成(附工程文件)

NE555构成多谐振荡器及三角波、正弦波的生成 续上一篇:NE555基本原理及相关公式的推导

qq_49979053的博客 5万+

深入剖析 C++ 红黑树实现与 set/map 容器封装(附完整可运行代码)

本文详细介绍了红黑树的实现原理及其在STL容器中的应用。红黑树通过5条核心性质确保自平衡,使树高维持在O(logn)级别,保证高效查找。文章从节点结构、迭代器实现到核心插入和平衡调整操作,完整展示了红黑树的实现过程,并基于红黑树封装了set和map容器。set实现元素有序存储,map通过键值对和operator[]提供便捷访问。测试代码验证了红黑树和容器的功能,包括插入、遍历、查找等操作。掌握红黑树有助于理解STL关联容器的底层机制,提升对自平衡数据结构的认识。

2401_88449824的博客 829

鸿蒙OS开机动画背后的秘密:从代码到视觉的完整解析(附源码分析)

本文深入解析了鸿蒙OS开机动画的系统级实现原理。从bootanimation服务的启动配置、与Render Service的协同,到基于VSync信号的帧率同步与绘制流水线,结合OpenHarmony源码进行了逐行解读。文章揭示了其事件驱动的优雅退出机制,并探讨了视频支持、多屏适配等高级特性与定制化可能,为开发者理解鸿蒙图形子系统提供了硬核技术视角。

sony5的博客 972

C++封装红黑树实现mymap和myset完整代码

通过封装红黑树实现map和set泛型设计:红黑树通过Value模板参数决定存储内容,通过KeyOfT仿函数提取键值进行比较。迭代器实现:中序遍历的步进逻辑是迭代器实现的核心,需同时处理左右子树与祖先关系。map的[]实现:依赖于insert的返回值,简洁高效。权限控制set的迭代器不允许修改键值,通过将Value模板参数设为const K实现;map则通过保护键不被修改。这种复用方式不仅减少了代码量,还体现了面向对象与泛型编程的强大结合。

m0_74824865的博客 84

DDR5中的On-Die Termination(ODT)详解:电阻值支持及其背后的秘密

DDR5支持多档ODT电阻值,范围从40Ω到480Ω,均基于240Ω标准参考电阻RZQR_{ZQ}RZQ​。不同电阻档位对应不同的信号负载和功耗需求。校准电压点关键,常用0.8×VDD进行精准调校。CA信号间ODT匹配必须严格控制,保证命令总线稳定。选择合适的ODT值是高速内存设计中不可忽视的细节。

weixin_43199439的博客 2097

MIMIC数据库简介

一 、MIMIC简介 MIMIC(Medical Information Mart for Intensive Care),是一个大型的公开数据库。该数据库记录了2001年至2019年期间贝斯以色列女狄肯斯医疗中心重症监护病房患者的相关数据,拥有4万多名患者的医疗健康数据和记录。 MIMIC数据库记录了人口统计学信息,如病人的性别、身高、宗教等情况。记录了实验室检验信息,如血常规,肝功能,肾功能等实验室检测数据。记录了患者的用药信息,如高血压患者服用了治疗高血压类药物等。记录了护理人员以及患者的护理级别等。

越努力 越幸运 1万+

【C++】基于红黑树的map和set封装实现

【C++】基于红黑树的map和set的封装实现

tan_run的博客 1035

第八章 GPU Scheduler 分析:8.3 drm_sched_entity — 调度实体

本文介绍了DRM GPU调度器中的drm_sched_entity结构,它作为用户提交命令进入调度器的提交通道,解决了归属、排序和公平性问题。文章首先分析了命令提交的归属需求,然后详细阐述了entity的核心模型,包括其职责、进程映射关系和核心字段。接着说明了用户态提交进入内核后的关键节点路径,以及entity内部的FIFO语义和激活机制。entity通过组织同一context的命令提交包为FIFO队列,使调度器能够在多个entity之间进行优先级和公平性调度,同时保证同一提交通道的顺序执行。

图形/计算GPU的驱动与虚拟化技术分享园地 653

封装红黑树代码-2 c++

封装红黑树代码

DefiniteGoal的博客 366

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

【C++高阶五】map&set对红黑树的封装

C++的STL库中把红黑树封装为了两个容器与本博客将基于红黑树来实现map和set的封装如果不了解红黑树,可见博客。

2201_75570391的博客 1246

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

封装红黑树代码-3 c++

封装红黑树代码-3

DefiniteGoal的博客 378

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

【C++】Set/Map使用红黑树封装

stl库中通过这种巧妙的方法使我们只需要我们实现一棵红黑树就可以复用形成set/map的底层,通过模版的形式让编译器去帮我们生成对应的代码,泛型思维。由以下代码我们可以分析出stl库中的set和map底层都是通过红黑树所实现的。

2301_81577798的博客 1万+

STL——红黑树的封装及map/set的模拟实现

前面的文章当中,我们介绍了红黑树的模拟实现,我们了解到红黑树是一颗不完全平衡二叉搜索树,我们之所以要学习红黑树,不仅仅是学习它实现的思维逻辑,更多的是通过红黑树去学习map和set的底层,前面我们介绍map/set的使用中我们提到,他们的底层是用红黑树去封装实现的,那么具体是怎么完成的呢?我们将在这一篇文章当中介绍。

f040731_007的博客 1077

红黑树封装map和set超详解

这篇博客完全是根据上篇博客红黑树来扩展的,代码的修改也是在红黑树那篇,大家可以先看看那篇代码再过来看看这篇更好食用哦!目录1.红黑树迭代器代码2.红黑树的insert代码3.map和set的封装4.最后代码总和5.最终测试1.红黑树迭代器代码将代码分成这几个.h / .cpp文件;

huajiahhhh的博客 786

用一颗红黑树同时封装出map和set

首先本文是对之前写过的红黑树进行修改,因为之前的红黑树只能存键值对,而现在我们是让set和map都能复用红黑树,所以我们这里介绍了如何修改红黑树中的模板参数已经增加了仿函数用来获取键值,后续我重点书写了迭代器的使用,这里非常重要,希望大家读完都能有所收获

weixin_47271425的博客 1498

红黑树源代码(进阶与细节解释)

看完前两篇的文章,相信对于红黑树有了一定的了解,知道红黑树是怎么样子进行插入的,是怎么样进行查找的,知道了底层是怎么样子的,知道了其与AVL树,二叉搜索树有什么区别了。但是对于set,map的底层又全是红黑树,set与map的区别就是其键值对一个是k,k型,一个是k,v型的,所以就有了封装,(对于封装后面会讲解什么是封装)二者底层全是同一份的红黑树,但是前面两篇文章的红黑树要不只能使用与k,k型,要不就是k,v型,所以就要对红黑树的源代码进行修改,进行细节上的修饰与进阶。

2301_81265915的博客 870

《封装红黑树实现mymap和myset》

iterator++

2401_87465145的博客 980

【C++篇】红黑树封装 实现map和set

本篇基于上篇【红黑树的实现】,代码也是基于红黑树的代码实现map和set的封装。

2401_82677021的博客 1645

红黑树封装 map/set 及其迭代器(C++)

使用红黑树封装map/set,并实现map/set的迭代器,支持成员访问、解引用、下标访问操作符++、-- 等功能.

Brant_zero的博客 3028

【C++】map和set封装

map和set的知识我们学习了,模拟实现我们已经实现了AVL树和红黑树。熟练知识点为map和set的使用提供了前提,手撕AVL树和红黑树让我了解到map和set的底层如何实现,有了知识点和两树的模拟铺垫,那我们该如何封装map和set呢?⭐主体​class setprivate:class mapprivate:{}//普通迭代器的时候,它是拷贝构造//const迭代器的时候,它是构造,支持用普通迭代器构造const迭代器{}💫解引用操作作用:返回对应结点数据的引用。

AAlykk的博客 1263

C++ 改造红黑树,封装map和set

C++ 改造红黑树,封装map和set

Wzs040810的博客 1759
上一篇: std::shared_ptr<void> 为什么可以正常调用类的析构
下一篇: 封装红黑树代码-2 c++
山有木兮啊
博客等级 码龄8年 135粉丝 132原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值