异或链表.

1.意义

其实双向链表每个节点在空间复杂度上还有优化的地方 比如在原本的双向链表的每一个节点中 都储存了三个内存 一个用于存储节点值 一个用于指向前置节点 一个用于指向后置节点 他的目的就在于通过任意节点可以访问到其前置节点以及后置节点 其实我们每个节点储存两个内存也可以达到这个目的 这就是我们今天所要讲述的异或链表

2.异或链表

异或链表是在双向链表的基础上进行了空间复杂度的优化 并且能够达到相同的功能
在这个链表中 每个节点都储存了两个内存 一个用于储存节点值 一个用于储存前置节点以及后置节点的地址值的异或结果
如果你想要访问当前节点的前置节点的话 那么你就可以通过当前节点的link(link就是用来储存前置节点地址值和后直节点地址值的异或结果的)异或后置节点的地址值即可获取到前置节点的地址值 然后就可以访问到当前节点的前置节点了
同理你想要访问当前节点的后置节点也是一样道理

3.代码实现

由于c或者c++这类的编程语言可以直接访问地址值 而Java等其他语言不能够直接访问地址值 所以我们不便使用Java去实现异或链表 所以通过c++来实现 这是异或链表的局限性

#include <iostream>
#include <vector>
#include <cstdint>
using namespace std;
// 定义一个结构体 视为节点类
struct Node {
    // 节点值
    int value;
    // 前置节点的地址值和后置节点地址值的异或结果
    Node* link;
};
// 定义一个函数 用于返回参数的异或结果
Node* XOR(Node* x, Node* y) {
    return (Node*)((uintptr_t)(x) ^ (uintptr_t)(y));
}
// 定义一个函数 用于遍历链表 并且同时打印节点值
void traverse(Node* head) {
    // 首先定义一个节点指针 用于保存前置节点的地址值
    Node* pre = nullptr;
    // 定义一个节点指针 用于指向当前节点
    struct Node* cur = head;
    // 定义一个节点指针 用于指向后置节点
    struct Node* next;
    // 如果当前节点不为空的话 那么直接打印当前节点的节点值
    while (cur != nullptr) {
        cout << cur->value << "->";
        next = XOR(pre, cur->link);
        pre = cur;
        cur = next;
    }
    // 等到循环结束以后 最后节点为空
    cout << "nullptr" << endl;
}
// 定义一个函数 用于往头部添加节点
void push(Node** head, int value) {
    // 首先创建一个结构体变量 设置该变量的value为指定参数
    Node* newNode = new Node();
    newNode->value = value;
    newNode->link = XOR(nullptr, *head);
    // 如果原链表中存在节点的话 那么需要更新头结点信息
    if (*head) {
        (*head)->link = XOR(newNode, XOR((*head)->link, nullptr));
    }
    // 更新头结点
    *head = newNode;
}
int main() {
    // 首先创建一个数组 用于存放节点值数据
    vector<int> result = { 1, 2, 3, 4, 5 };
    Node* head = nullptr;
    for (int i = result.size() - 1; i >= 0; --i) {
        push(&head, result[i]);
    }
    traverse(head);
    return 0;
}

4.测试结果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

axihaihai

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值