Why deletion of elements of hash table using doubly-linked list is O(1)?

前端 未结 8 1301
野的像风
野的像风 2020-12-23 10:20

On CLRS\'s textbook \"Introduction to Algorithm\", there\'s such paragraph on pg. 258.

We can delete an element in O(1) time if the lists are doubly linked. (Note th

相关标签:
8条回答
  • 2020-12-23 11:01

    In general you are correct - the algorithm you posted takes an element itself as input though and not just its key:

    Note that CHAINED-HASH-DELETE takes as input an element x and not its key k, so that we don't have to search for x first.

    You have the element x - since it is a double linked list you have pointers to predecessor and successor, so you can fix those elements in O(1) - with a single linked list only the successor would be available, so you would have to search for the predecessor in O(n).

    0 讨论(0)
  • 2020-12-23 11:04

    The textbook is wrong. The first member of a list has no usable "previous" pointer, so additional code is needed to find and unlink the element if it happens to be the first in the chain (typically 30 % of the elements are the head of their chain, if N=M, (when mapping N items into M slots; each slot having a separate chain.))

    EDIT:

    A better way then using a backlink, is to use a pointer to the link that points to us (typically the ->next link of the previous node in the list)

    struct node {
       struct node **pppar;
       struct node *nxt;
       ...
       }
    

    deletion then becomes:

    *(p->pppar) = p->nxt;
    

    And a nice feature of this method is that it works equally well for the first node on the chain (whose pppar pointer points to some pointer that is not part of a node.

    UPDATE 2011-11-11

    Because people fail to see my point, I'll try to illustrate. As an example there is a hashtable table (basically an array of pointers) and a buch of nodes one, two, three one of which has to be deleted.

        struct node *table[123];
        struct node *one, *two,*three;
        /* Initial situation: the chain {one,two,three}
        ** is located at slot#31 of the array */
        table[31] = one, one->next = two , two-next = three, three->next = NULL;
                    one->prev = NULL, two->prev = one, three->prev = two;
    
    
        /* How to delete element one :*/
        if (one->prev == NULL) {
                table[31] = one->next;
                }
        else    {
                one->prev->next = one->next
                }
        if (one->next) {
                one->next->prev = one->prev;
                }
    

    Now it is obvious that the obove code is O(1), but there is something nasty: it still needs array, and the index 31, so in most cases a node is "self contained", and a pointer to a node is sufficient to delete it from its chain, except when it happens to be the first node in its chain; additional information will then be needed to find table and 31.

    Next, consider the equivalent structure with a pointer-to-pointer as a backlink.

        struct node {
                struct node *next;
                struct node **ppp;
                char payload[43];
                };
    
        struct node *table[123];
        struct node *one, *two,*three;
        /* Initial situation: the chain {one,two,three}
        ** is located at slot#31 of the array */
        table[31] = one, one-next = two , two-next = three, three->next = NULL;
                    one->ppp = &table[31], two->ppp = &one->next, three->ppp = &two-next;
    
        /* How to delete element one */
        *(one->ppp) = one->next;
        if (one->next) one->next->ppp = one->ppp;
    

    Note: no special cases, and no need to know the parent table. (consider the case where there is more than one hashtable, but with the same nodetypes: the delete operation would still need to know from which table the node should be removed).

    Often, in the {prev,next} scenario, the special cases are avoided by adding a dummy node at the start of the double linked list; But that needs to be allocated and initialised, too.

    0 讨论(0)
提交回复
热议问题