An ordinary doubly linked list stores addresses of the previousand next list items in each list node, requiring two address fields:
... A B C D E ...
–> next –> next –> next –>
<– prev <– prev <– prev <–
An XOR linked list compresses the same information into one addressfield by storing the bitwise XOR of the address for previous andthe address for next in one field:
... A B C D E ...
<–> A⊕C <-> B⊕D <-> C⊕E <->
When you traverse the list from left to right: supposing you areat C, you can take the address of the previous item, B, and XOR it with thevalue in the link field (B⊕D).You will then have the address for D and you can continue traversing the list.The same pattern applies in the other direction.
The key is the first operation, and the properties of XOR:
§ X⊕X=0
§ X⊕0=X
§ X⊕Y=Y⊕X
§ (X⊕Y)⊕Z=X⊕(Y⊕Z)
The R2 register always contains the XOR of the address of currentitem C with the address of the predecessor item P: C⊕P. The Link fields in the records contain theXOR of the left and right successor addresses, say L⊕R. XOR of R2 (C⊕P) with the current link field (L⊕R) yields C⊕P⊕L⊕R.
§ If the predecessor was L, the P(=L) and L cancelout leaving C⊕R.
§ If the predecessor had been R, the P(=R) and Rcancel, leaving C⊕L.
In each case, the result is the XOR of the current address withthe next address. XOR of this with the current address in R1 leaves the nextaddress. R2 is left with the requisite XOR pair of the (now) current addressand the predecessor.
9 struct xorlist{
10 int data;
11 struct xorlist* next;
12 };
13
14
15 /* @func: create xorlist according to input array.
16 * @params: an array that need to transform to xorlist.
17 * @ret: the header of xor list
18 */
19 xorlist* create_xorlist(int arr[], int count){
20 int index = 0;
21 if (NULL == arr)
22 return NULL;
23
24 xorlist* head = NULL;
25 xorlist* prevnode = NULL;
26 xorlist* node = NULL;
27 xorlist* nextnode = NULL;
28
29 head = node = (xorlist*)malloc(sizeof(xorlist));
30 node->data = arr[index];
31 --count;
32
33 while (count){
34 ++index;
35 nextnode = (xorlist*)malloc(sizeof(xorlist));
36 nextnode->data = arr[index];
37 node->next = (xorlist*)((int)prevnode ^ (int)nextnode);
38 prevnode = node;
39 node = nextnode;
40 --count;
41 };
42
43 node->next = prevnode;
44
45 return head;
46 }
48 /* @func: delete the xorlist
49 * @params: the header of xorlist that need to be deleted
50 *
51 */
52 void destroy_xorlist(xorlist* head){
53 if (NULL == head)
54 return;
55 xorlist* prevnode = NULL;
56 xorlist* node = NULL;
57 xorlist* nextnode = NULL;
58
59 node = head;
60 while (nextnode = (xorlist*)((int)node->next ^ (int)prevnode)){
61 free(prevnode);
62 prevnode = node;
63 node = nextnode;
64 }
65 free(node);
66 free(prevnode);
67 }
68
69 /* @func: insert one element into xorlist
70 * @params: the new xorlist element
71 * @ret: the header of the xorlist
72 */
73 xorlist* insert_xorlist(xorlist* head, int value){
74 if (NULL == head)
75 return NULL;
76 xorlist* prevnode = NULL;
77 xorlist* node = NULL;
78 xorlist* nextnode = NULL;
79
80 node = head;
81 while (nextnode = (xorlist*)((int)(node->next)^(int)prevnode)){
82 prevnode = node;
83 node = nextnode;
84 }
85 xorlist* tail = (xorlist*)malloc(sizeof(xorlist));
86 node->next = (xorlist*)((int)prevnode ^ (int)tail);
87 tail->data = value;
88 tail->next = node; //namely xor zero
89
90 return head;
91 }
92
93 /* @func: delete one element from xorlist
94 * @params: the value of element that should be deleted
95 * @ret: the header of the xorlist
96 */
97 xorlist* delete_xorlist(xorlist* head, int value){
98 if (NULL == head)
99 return NULL;
100 xorlist* prevnode = NULL;
101 xorlist* node = NULL;
102 xorlist* nextnode = NULL;
103
104 node = head;
105 while (nextnode = (xorlist*)((int)node->next^(int)prevnode)){
106 if (value == node->data){
107 if (node == head){
108 nextnode->next = (xorlist*)((int)node ^ (int)nextnode->next);
109 head = nextnode;
110 } else {
111 prevnode->next = (xorlist*)(((int)node^(int)prevnode->next)^(int)nextnode);
112 nextnode->next = (xorlist*)((int)prevnode ^ ((int)node^(int)nextnode->next));
113 }
114
115 free(node);
116 break;
117 }
118 prevnode = node;
119 node = nextnode;
120 }
122 //delete the tail node
123 if (node->data == value){
124 prevnode->next = (xorlist*)((int)node ^ (int)prevnode->next);
125 free(node);
126 }
122 return head;
123 }
124
125 /* @func: tranverse the xorlist.
126 * @params: the header of xorlist.
127 * @ret: return the header of xorlist.
128 */
129 xorlist* tranverse_xorlist(xorlist* head){
130 if (NULL == head)
131 return NULL;
132 xorlist* prevnode = NULL;
133 xorlist* node = NULL;
134 xorlist* nextnode = NULL;
135
136 node = head;
137 while (nextnode = (xorlist*)((int)node->next^(int)prevnode)){
138 printf(" %d ", node->data);
139 prevnode = node;
140 node = nextnode;
141 }
142 printf(" %d \n", node->data);
143 return head;
144 }
145
146 int main(){
147 int array[] = {3, 4, 8, 9, 1, 7, 5, 6, 11};
148 xorlist* head = create_xorlist(array, sizeof(array)/sizeof(array[0]));
149 head = tranverse_xorlist(head);
150 head = insert_xorlist(head, 2);
151 head = tranverse_xorlist(head);
152 head = delete_xorlist(head, 1);
153 head = tranverse_xorlist(head);
154
155 destroy_xorlist(head);
156 return 0;
157 }