XOR链表的C代码

Mor*_*Eru 11 c linked-list xor

我一直在尝试实现XOR链接列表及其操作,但我无法正确执行.

是否可以在C中实现它,因为XOR链接列表涉及对地址的操作?

如果给出一些实际的工作代码,我将非常感激.

Mar*_*ins 17

这是一个我以前没见过的有趣的想法.凭借今天相当丰富的内存,它看起来很复杂,但收益微不足道(尽管不是所有平台都充满了内存). 编辑在完成我的实际工作时,我的思绪一直在回归,所以我添加了创建新节点的功能并将其放在给定的一端.现在比较漂亮.addnode和traverse函数都是对称的,这很酷.两者都不需要知道方向.只需给它列表的一端,它们就能正常运行.

根据Darron的评论(谢谢),我将int更改intptr_t为可移植性.

#include <stdio.h>
#include <malloc.h>
#include <stdint.h>  // gcc needs this for intptr_t.  

typedef struct xorll {
   int  value;
   struct xorll  *np;
}  xorll;


// traverse the list given either the head or the tail
void traverse( xorll *start )  // point to head or tail
{
   xorll *prev, *cur;

   cur = prev = start;
   while ( cur )
      {
      printf( "value = %d\n", cur->value );
      if ( cur->np == cur )
         // done
         break;
      if ( cur == prev )
         cur = cur->np;   // start of list
      else {
         xorll *save = cur;
         cur = (xorll*)((uintptr_t)prev ^ (uintptr_t)cur->np);
         prev = save;
         }
      }
}

// create a new node adding it to the given end and return it
xorll* newnode( xorll *prev, xorll *cur, int value )
{
   xorll *next;

   next = (xorll*)malloc( sizeof( xorll ));
   next->value = value;
   next->np = cur;  // end node points to previous one

   if ( cur == NULL )
      ; // very first node - we'll just return it
   else if ( prev == NULL ) {
      // this is the second node (they point at each other)
      cur->np = next;
      next->np = cur;
      }
   else {
      // do the xor magic
      cur->np = (xorll*)((uintptr_t)prev ^ (uintptr_t)next);
      }

   return next;
}



int main( int argc, char* argv[] )
{
   xorll *head, *tail;
   int   value = 1;

   // the first two nodes point at each other.  Weird param calls to
   // get the list started
   head = tail = newnode( NULL, NULL, value++ );
   tail = newnode( NULL, tail, value++ );

   // now add a couple to the end
   tail = newnode( tail->np, tail, value++ );
   tail = newnode( tail->np, tail, value++ );

   // this is cool - add a new head node
   head = newnode( head->np, head, 999 );


   printf( "Forwards:\n" );
   traverse( head );
   printf( "Backwards:\n" );
   traverse( tail );


}
Run Code Online (Sandbox Code Playgroud)

  • 您应该使用intptr_t使此代码可移植.在某些平台上,指针不适合unsigned int. (3认同)

sch*_*hot 9

由于无法对指针执行xor操作,因此必须将地址转换为整数类型以执行xor并将结果转换回右指针类型.

据我所知,C99只有两种整数类型,可以保证转换到具有已定义行为的指针(=将原始指针返回):intptr_tuintptr_t来自<stdint.h>.请注意,这两种类型都是可选的,因此您的实现可能没有它们.

转换示例,假设a并且b是有效指针struct node:

#include <stdint.h>

/* creating an xor field */
uintptr_t x = (uintptr_t) (void *) a ^ (uintptr_t) (void *) b;
/* reconstructing an address */
a = (void *) (x ^ (uintptr_t) (void *) b);
Run Code Online (Sandbox Code Playgroud)

我不是100%确定void *需要额外的演员表,如果他们不是,请有人纠正我.有关(u)intptr_t类型的更多信息,请参见C99标准的§7.18.1.4 .

  • 我认为确实有必要对`void *`进行强制转换。该标准仅保证在`void *`和`(u)intptr_t`之间(如果您所说的那样存在),然后在指向数据类型的指针和`void *`之间进行转换。但这对直接投射没有任何帮助,因此您应该避免使用它以确保安全。 (2认同)

Dar*_*rio 5

是否可以在C中实现它,因为XOR链接列表涉及对地址的操作?

是的.地址是指针,指针是数字*,数字允许XOR(即a ^ b).

查一查 是什么做的,你应该能够做到的实现.

*至少,您可以将它们视为数字 - 但可能需要显式强制转换.

  • @Job:标准没有定义"无符号"的强制转换,如果可能,甚至可能导致信息丢失.`unsigned`和指针可能有不同的宽度. (2认同)