Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the pointer-to-pointer technique for the simpler traversal of linked lists? [duplicate]

Tags:

c++

c

linked-list

Ten years ago, I was shown a technique for traversing a linked list: instead of using a single pointer, you used a double pointer (pointer-to-pointer).

The technique yielded smaller, more elegant code by eliminating the need to check for certain boundary/edge cases.

Does anyone know what this technique actually is?

like image 470
Aaron Fi Avatar asked Jul 05 '10 23:07

Aaron Fi


3 Answers

I think you mean double pointer as in "pointer to a pointer" which is very efficient for inserting at the end of a singly linked list or a tree structure. The idea is that you don't need a special case or a "trailing pointer" to follow your traversal pointer once you find the end (a NULL pointer). Since you can just dereference your pointer to a pointer (it points to the last node's next pointer!) to insert. Something like this:

T **p = &list_start;
while (*p) {
   p = &(*p)->next;
}
*p = new T;

instead of something like this:

T *p = list_start;
if (p == NULL) {
    list_start = new T;
} else {
    while (p->next) {
        p = p->next;
    }
    p->next = new T;
}

NOTE: It is also useful for making efficient removal code for a singly linked list. At any point doing *p = (*p)->next will remove the node you are "looking at" (of course you still need to clean up the node's storage).

like image 179
Evan Teran Avatar answered Oct 18 '22 11:10

Evan Teran


By "double-pointer", I think you mean "pointer-to-pointer". This is useful because it allows you to eliminate special cases for either the head or tail pointers. For example, given this list:

struct node {
    struct node *next;
    int key;
    /* ... */
};

struct node *head;

If you want to search for a node and remove it from the list, the single-pointer method would look like:

if (head->key == search_key)
{
    removed = head;
    head = head->next;
}
else
{
    struct node *cur;

    for (cur = head; cur->next != NULL; cur = cur->next)
    {
        if (cur->next->key == search_key)
        {
            removed = cur->next;
            cur->next = cur->next->next;
            break;
         }
    }
}

Whereas the pointer-to-pointer method is much simpler:

struct node **cur;

for (cur = &head; *cur != NULL; cur = &(*cur)->next)
{
    if ((*cur)->key == search_key)
    {
        removed = *cur;
        *cur = (*cur)->next;
        break;
    }
}
like image 42
caf Avatar answered Oct 18 '22 13:10

caf


I think you mean doubly-linked lists where a node is something like:

struct Node {
(..) data // The data being stored in the node, it can be of any data type
Node *next; // A pointer to the next node; null for last node
Node *prev; // A pointer to the previous node; null for first node
}
like image 2
chocolate_jesus Avatar answered Oct 18 '22 12:10

chocolate_jesus