C 请给出我应该使用哪种数据结构的建议

C 请给出我应该使用哪种数据结构的建议,c,data-structures,struct,C,Data Structures,Struct,代码是C语言。我有两种类型的对象(structs)具有父子关系,一种父类型可以有0或更多子类型,一个子类型不能有自己的子类型。我需要O(1)父级查找(通过uIDstruct成员)和子级查找(也通过uIDstruct成员),而不知道谁是它的父级。一旦我有了一个指向父对象的指针,我希望能够遍历它的子对象。当我有一个指向孩子的指针时,我想知道谁是孩子的父母。在程序执行期间,可以删除或插入任何子项或父项,并且子项可以更改其父项。删除父对象时,其子对象也应删除。所有这些都应该在多线程环境中完成,所以我需要

代码是C语言。我有两种类型的对象(
structs
)具有父子关系,一种父类型可以有
0
或更多子类型,一个子类型不能有自己的子类型。我需要
O(1)
父级查找(通过
uID
struct成员)和子级查找(也通过
uID
struct成员),而不知道谁是它的父级。一旦我有了一个指向父对象的指针,我希望能够遍历它的子对象。当我有一个指向孩子的指针时,我想知道谁是孩子的父母。在程序执行期间,可以删除或插入任何子项或父项,并且子项可以更改其父项。删除父对象时,其子对象也应删除。所有这些都应该在多线程环境中完成,所以我需要线程安全的读取(我将使用只读锁进行密钥搜索,并使用读写锁进行插入/删除/重新建立父子关系)。您推荐什么样的数据结构

增加:

目前,我正在尝试使用uthash库()实现它:

问题是,当一个新的孩子出生时,它最终会被甩在后面
与“兄弟”无关。如果我理解正确:

struct child;  /* Forward declaration */

struct parent {
    int child_count;
    /* Other info */
    struct child child[];  /* Flex array, must be the last field */
};

struct child {
    struct parent *parent;
    /* Other info */
};

struct parent *parent_registry;  /* Array of parents, index is the ID */
struct child *child_registry;  /* Array of children, index is the ID */
也许这太简单了,特别是在重新租用时,因为您必须移动阵列切片,但这可能是一个好的开始。或者,您可以预先分配(即摊销分配)并将所有可用数组位置(通过数组索引)链接在一起,以最小化内存移动。

如何:

  • 父母的哈希表
  • 一个单独的儿童哈希表
  • 每个子对象中指向其父对象的链接
  • 每个子级中指向其下一个和上一个同级的链接(双链接列表)
  • 每个父对象中指向其第一个子对象的链接
  • 哈希表可能不完全是O(1)查找,但它们会很接近。您可能可以为它们使用一个现有的、完善的库

    在线程安全方面,您可以为两个散列(用于项目插入/删除)都使用互斥锁,并且在每个父级中都有一个互斥锁,用于在操作它或它的任何子级时使用。当然,要小心死锁:例如,如果改变孩子的父母需要同时锁定新旧父母,请确保按照一致的顺序进行操作


    当然,找到无锁结构会更好,但我真的不能在这方面给你建议,除非研究一下,看看你是否能找到任何合适的结构。

    你说的“查找”是什么意思?天真的方法:让每个孩子都有一个上一个、下一个和父指针,并给每个家长一个指向第一个孩子的指针——也就是说,保持孩子的双链接列表。所有指针都应该是原子的,以允许对关系结构进行无锁操作。通过查找,我的意思是,如果一个对象(父对象或子对象)有uID XXXX,并且我有该uID,我希望在内存中获取结构对象的地址。我明白了。O(1)我想可以用哈希表进行查找。如果ID是连续的,那么一个简单的数组甚至可以做到这一点。(即,具有普通、完美哈希函数的哈希表)ID不是连续的,它们是64位唯一ID。是的,我也倾向于使用哈希表。谢谢,是的,多线程编程非常容易出错。B+树没有锁,否则对这个问题来说,它们会是一种过度的杀伤力?B+树(以及一般的树)可以有两个以上的级别,所以一个节点可以同时是父节点和子节点。它似乎不符合您的规格。谢谢朋友,我不知道那些flex阵列,转到rtfm:)
    struct child;  /* Forward declaration */
    
    struct parent {
        int child_count;
        /* Other info */
        struct child child[];  /* Flex array, must be the last field */
    };
    
    struct child {
        struct parent *parent;
        /* Other info */
    };
    
    struct parent *parent_registry;  /* Array of parents, index is the ID */
    struct child *child_registry;  /* Array of children, index is the ID */