Подтвердить что ты не робот

Возможно ли реализовать XOR LinkedList в Java (DLL с одним указателем)

Связанные списки XOR - это в основном эффективная версия связанного списка, в которой хранятся адреса предыдущих и следующих узлов для реализации Doubly Linked List с использованием только одного указателя. Мне было интересно, возможно ли реализовать на 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;
}
4b9b3361

Ответ 1

Нет, вы не можете сделать это в Java вообще - вы не можете получить адрес объекта или вычислить ссылку на объект из других значений. Это позволяет сборщику мусора перемещать объекты, не мешая программе.

Это также очень плохая идея в С++.

Если вас беспокоит нехватка памяти в связанном списке, вы можете сохранить несколько элементов за node. Если node содержит ссылки prev, next и items [16], и вы всегда убедитесь, что ваши узлы по меньшей мере наполовину заполнены, тогда он будет использовать меньше памяти, чем обычный XOR-список.

Ответ 2

Пока вы не можете использовать raw-указатели в 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;
}