C如何使用XOR运算 古法制作链表(异或链表)
依旧是看到Tsoding的视频
链接如下
【编程派对小技巧 | Tsoding】 https://www.bilibili.com/video/BV1iu2mByEXB
不过还是不如自己看源代码
手机UI点这个
<iframe src="//player.bilibili.com/player.html?isOutside=true&aid=115687024494780&bvid=BV1iu2mByEXB&cid=34604843364&p=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true">\
思路应该是:
我们有异或运算符,(它的逆运算是自己)就是说它可以使用前两个值推导出第三个值:
例如加入时可以替换掉end迭代器 (和cpp指向最后一个元素的后面不同,这里☞最后一个元素) 替换成加入的新地址,旧的变为^=新地址
例如遍历时传入迭代器(传入end会反转)?更新表达式调用一个prev(每次操作前要更新为0)用于维护上一个值,然后Node next = (Node)(node->xorn ^ *prev);安全起见可以归零 虽然这玩意本身就很难安全,没什么人用
指针不能直接异或运算,我们可以使用结构体包含值 (uintptr_t类型),然后辅助运算
如下,倒着看一遍
比如要先存入数据,就要维护一个当前值和一个prev值,在链表为空的时候,需要CreateNode函数创建节点再处理维护begin和end,不为空就可以正常异或赋值传值
Node* CreateNode(int value) {
Node* node = (Node*)calloc(1, sizeof(Node));
node->value = value;
node->xorn = 0;
return node;
}
void ll_append(XORLinkedList* ll,int value){
if(ll->begin == NULL){
assert(ll->end == NULL);
Node *node = CreateNode(value);
ll->begin = node;
ll->end = node;
return;
}
Node *node = CreateNode(value);
ll->end->xorn ^= (uintptr_t)node;
node->xorn = (uintptr_t)ll->end;
ll->end = node;
}
遍历时需要维护prev
Node* NodeNext(Node* node,uintptr_t * prev ){
Node *next = (Node*)(node->xorn ^ *prev);
//Node *next = (Node* )((Node*).xorn ^ (Node*)prev);
*prev = (uintptr_t)node;
return next;
}
然后就
for(Node* iter = eg.begin; iter != NULL;iter = NodeNext(iter, &prev)) {
printf("%d ", iter->value);
}
ll_append 0~9
输出0 1 2 3 4 5 6 7 8 9
其实还是看一遍源码更有用()

浙公网安备 33010602011771号