C 从随机id检索元素的最佳算法

C 从随机id检索元素的最佳算法,c,algorithm,data-structures,C,Algorithm,Data Structures,我目前正在努力寻找适合我的情况的最佳数据结构/算法: 我接收单个唯一的随机id(uint32_t),并创建一个与每个新id关联的元素 我需要从id中检索元素 我还需要按照创建顺序从任何元素(甚至id)访问下一个和上一个元素。创建的顺序主要取决于当前元素,它总是可以在一旁访问,因此新元素应该是它的下一个元素 以下是一个例子: (12) <-> (5) <-> (8) <-> (1) ^ ^ '----------

我目前正在努力寻找适合我的情况的最佳数据结构/算法:

我接收单个唯一的随机id(uint32_t),并创建一个与每个新id关联的元素

  • 我需要从id中检索元素

  • 我还需要按照创建顺序从任何元素(甚至id)访问下一个和上一个元素。创建的顺序主要取决于当前元素,它总是可以在一旁访问,因此新元素应该是它的下一个元素

  • 以下是一个例子:

    (12) <-> (5) <-> (8) <-> (1)
     ^                        ^
     '------------------------'
    
    另一个想法可能是使用哈希映射,但是我需要找到正确的哈希函数。但不完全确定它在实践中是否总是比AVL更适合这种数量的元素。这取决于哈希函数

    <>这是一个好主意吗?或者我应该考虑其他的情况吗?

    谢谢


    PS:我不是一个试图让你做作业的学生,我只是想开发一个简单的窗口管理器(只是为了好玩)。

    我的建议是,你可以使用两种数据结构的组合—一个列表来存储插入的元素,一个哈希映射或二叉搜索树来实现关联数组(map)在id和列表节点之间。您将使用关联数组执行搜索,并能够使用列表访问相邻元素。删除也相对容易,但需要从这两个结构中删除


    如果使用二元搜索树,则查找/插入/删除的复杂性将是
    log(n)
    ,如果使用哈希表,则预期的复杂性是恒定的

    您正在寻找java中所称内容的一些变体

    这基本上是a和a(双向)的组合

    链表具有所需顺序的元素。在已知位置插入元素(假设您有指向正确位置的指针)是在
    O(1)
    中完成的。删除也是如此。链表包含按所需顺序排列的所有元素

    第二种数据结构是哈希映射(或树映射)。此数据结构从键(您的唯一id)映射到链表中的指针。通过这种方式,给定一个id,您可以快速找到它在链表上的位置,并且从那里您可以轻松地访问下一个和上一个元素

    用于插入的高级伪代码:

    insert(x, v, y): //insert key=x value=v, after element with key=y
       if x is in hash-table:
            abort
       p = find(hash-table,y) //p is a pointer
       insert_to_list_after(x,v,p) //insert key=x,value=v right after p
       add(hash-table,x,p) //add x to the hash-table, and make it point to p.
    
    用于搜索的高级伪代码:

    search(x):
        if x is not in hash-table:
            abort
        p = find(hash-table,x)
        return p->value;
    
    删除应该与插入非常相似(并且具有相同的时间复杂性)

    请注意,查找
    x
    之后的元素也相当容易:

    p = find(hash-table,x)
    if (p != NULL && p->next != NULL):
        return p->next->value
    

    <>你一定要考虑数据结构。 它似乎非常适合您的情况,因为它有一个预期的
    O(log(n))
    insert/search/delete,如果您有一个指向节点的指针,只需移动该指针即可在
    O(1)
    中找到上一个和下一个元素


    结论是,如果您刚刚创建了一个节点,就有一个指向它的指针,您可以在
    O(1)
    time中找到prev/next元素。

    id可以是唯一的,也可以是随机的,但不能两者都有。。。。一旦使用了唯一的ID,它再次被使用的概率将变为0,而未使用的ID的概率为1/N。因此,它不是随机的。@abelenky它仍然可以是随机的,只是不是一致的i.i.d随机的。@abelenky好吧,你可能是对的。我的意思是这些唯一的IDS不服从任何命令(如果是的话,我不应该考虑)。这是我使用两个数据结构的第一个想法:一个是用ID搜索,另一个是双链表来查找下一个和PREV元素。谢谢,我去看看。我只需要找到一个好的和快速的散列函数。嗨,这基本上就是我所描述的。AVL/Hashmap通过id检索元素。每个元素指向其下一个和上一个元素,就像list@Ervadac嗯,最重要的区别是,我建议您将两个数据结构分开。这将使你的事情变得更容易。此外,哈希表可能比AVL树更好。
    search(x):
        if x is not in hash-table:
            abort
        p = find(hash-table,x)
        return p->value;
    
    p = find(hash-table,x)
    if (p != NULL && p->next != NULL):
        return p->next->value