xor-linked-list.c (1793B)
1 #include <assert.h> 2 #include <stdint.h> 3 #include <stdio.h> 4 5 struct node 6 { 7 uintptr_t delta; 8 int data; 9 }; 10 11 struct node* next_node(struct node* prev, struct node* current) 12 { 13 assert(current); 14 return (struct node*)((uintptr_t)prev ^ current->delta); 15 } 16 17 18 void insert(struct node* p, struct node* c, struct node* n) 19 { 20 if (c) 21 { 22 assert(!c->delta); 23 c->delta ^= (uintptr_t)p ^ (uintptr_t)n; 24 25 } 26 if (p) 27 { 28 p->delta ^= (uintptr_t)c ^ (uintptr_t)n; 29 assert(p->delta); 30 } 31 if (n) 32 { 33 n->delta ^= (uintptr_t)c ^ (uintptr_t)p; 34 assert(n->delta); 35 } 36 } 37 38 void append(struct node* p, struct node* c, struct node* n) 39 { 40 assert(n); 41 assert(!n->delta); 42 assert(!next_node(p, c)); 43 c->delta ^= (uintptr_t)n; 44 n->delta = (uintptr_t)c; 45 } 46 47 void extract(struct node* prev, struct node* get) 48 { 49 assert(prev); 50 assert(get); 51 52 struct node* next = next_node(prev, get); 53 if (prev) 54 prev->delta ^= (uintptr_t)get ^ (uintptr_t)next; 55 if (next) 56 next->delta ^= (uintptr_t)get ^ (uintptr_t)prev; 57 get->delta = 0; 58 } 59 60 void advance(struct node** prev, struct node** current) 61 { 62 struct node* p = *current; 63 *current = next_node(*prev, *current); 64 *prev = p; 65 } 66 67 static struct node nodes[5]; 68 static struct node stray = {0, 11}; 69 70 int main() 71 { 72 for (unsigned i = 0; i < 5; ++i) 73 nodes[i].data = i; 74 75 append(NULL, nodes+0, nodes+1); 76 append(nodes+0, nodes+1, nodes+3); 77 append(nodes+1, nodes+3, nodes+2); 78 append(nodes+3, nodes+2, nodes+4); 79 insert(nodes+2, &stray, nodes+4); 80 extract(nodes+1, nodes+3); 81 82 puts("Forward:"); 83 for (struct node* current = nodes, *last = NULL; current; advance(&last, ¤t)) 84 printf(" %p = %d\n", current, current->data); 85 puts("\nReverse:"); 86 for (struct node* current = nodes+4, *last = NULL; current; advance(&last, ¤t)) 87 printf(" %p = %d\n", current, current->data); 88 }