是否可以在Java中实现XOR LinkedList(带有单指针的DLL)

时间:2015-10-23 08:44:26

标签: java xor-linkedlist

XOR链表基本上是链表的高效版本,它存储前一节点和下一节点的地址,仅使用单个指针实现双链表。 我想知道是否有可能在Java中实现,因为它没有指针。 在C中,这可以通过

来完成
 /* Insert a node at the begining of the XORed linked list and makes the
    newly inserted node as head */
void insert(struct node **head_ref, int data)
{
    // Allocate memory for new node
    struct node *new_node  = (struct node *) malloc (sizeof (struct node));
    new_node->data = data;

    /* Since new node is being inserted at the begining, npx of new node
       will always be XOR of current head and NULL */
    new_node->npx = XOR(*head_ref, NULL);

    /* If linked list is not empty, then npx of current head node will be XOR 
       of new node and node next to current head */
    if (*head_ref != NULL)
    {
        // *(head_ref)->npx is XOR of NULL and next. So if we do XOR of 
        // it with NULL, we get next
        struct node* next = XOR((*head_ref)->npx,  NULL);
        (*head_ref)->npx = XOR(new_node, next);
    }

    // Change head
    *head_ref = new_node;
}

2 个答案:

答案 0 :(得分:5)

不,你根本不可能在Java中这样做 - 你无法获取对象的地址或从其他值计算对象的引用。这允许垃圾收集器在不干扰程序的情况下移动对象。

在C ++中,这也是一个非常糟糕的主意。

如果您担心链接列表中的内存开销,则可以为每个节点存储多个项目。如果一个节点有prev,next和items [16]引用,并且你总是确保你的节点至少有一半,那么它将比一般的XOR列表使用更少的内存。

答案 1 :(得分:2)

虽然你不能真正使用Java中的原始指针,但我们可以保持接近XOR链表的精神。指针只是内存字节数组的索引,java数组只是添加偏移量并缩放索引。如果有效负载是单个int,我们可以轻松地使用int[]作为“内存”,并避免一些奇怪的转换。它仍然有点烦人,因为我们还必须实现自己的分配器,但这在这个受限制的上下文中更简单,因为所有块都具有相同的大小。

所以,这是一个尝试。没有测试过。你更了解这个想法。

int[] memory = new int[1024]; // enough for 512 nodes
int free; // pointer to free list

int insert(int head, int data) throws Exception
{
    int node = alloc();
    memory[node] = head;  // normal link here (xored with zero)
    memory[node + 1] = data;
    memory[head] ^= node; // old head gets a xor-link
    return node;          // return new head
}

void init()
{
    // put nodes in free list
    free = 2;
    for (int i = 2; i < memory.length - 2; i += 2)
        memory[i] = i + 2;
}

int alloc() throws Exception
{
    if (free == 0)
        throw new Exception(); // throw a better one
    int res = free;
    free = memory[free];
    return res;
}

void free(int ptr)
{
    memory[ptr] = free;
    free = ptr;
}