“内存高效的双向链表”如何运作?

时间:2014-09-13 05:18:00

标签: c algorithm data-structures xor-linkedlist mem.-efficient-linkedlist

Data Structures and Algorithms Made Easystruct内存有效内存列表中给出如下,

struct LinkNode
{
 int data;
 struct LinkNode* ptrdiff;
}

ptrdiff中,将完成上一个和下一个节点的xoring。例如,上一个节点的地址 100 ,下一个节点地址 500

因此,在ptrdiff地址中 400 。现在,如何通过了解其地址的xoring来移动到下一个或上一个节点(就像我们在双向链接列表中所做的那样)?

我错过了这里的任何一步吗?

2 个答案:

答案 0 :(得分:5)

第一个节点没有上一个节点,最后一个节点没有下一个节点...所以想想第一个节点之前的节点地址和最后一个节点之后的节点地址为0.这就足以启动遍历,当你遍历时,你总是拥有前面节点的地址,这样你就可以确定后续节点的地址。这是遍历此类列表并打印数据的示例...将第一个或最后一个节点的地址传递给printxorlist,它将向前或向后打印:

void printxorlist(struct LinkNode* node)
{
    struct LinkNode* prev = NULL;
    while (node)
    {
        printf("%d\n", node->data);
        struct LinkNode* next = (struct LinkNode*)((intptr_t)node->ptrdiff ^ (intptr_t)prev);
        prev = node;
        node = next;
    }
}

请注意,我们必须转换node->ptrdiff,因为它实际上没有正确的类型。更好的方法是正确宣布:

struct LinkNode
{
    int data;
    intptr_t ptrdiff;
}

然后

void printxorlist(struct LinkNode* node)
{
    struct LinkNode* prev = NULL;
    while (node)
    {
        printf("%d\n", node->data);
        struct LinkNode* next = (struct LinkNode*)(node->ptrdiff ^ (intptr_t)prev);
        prev = node;
        node = next;
    }
}

答案 1 :(得分:0)

在这种类型的链表中,不能从任意节点的地址遍历。因为您需要一些关于前任地址或后继地址的额外信息。但是从第一个节点(前任地址= 0,因为不是任何前任)或最后一个节点(后继地址= 0,因为不是任何后继节点)遍历是可能的。