异或链表(XOR Linked List)
一、常见的链表
1、单链表(Singly Linked List)
构成:每个节点包含数据(data)和后继节点的地址(next)
2、双向链表
构成:每个节点包含数据(data)、前驱的地址(prev)、后继的地址(next)
优势:删除或添加元素不需要移动数据,可以双向遍历
3、异或链表(XOR Linked List)
构成:每个节点包含数据(data)、前驱地址和后继地址的异或
是一种实现双向链表的方法,它 增加了代码复杂度,降低了空间复杂度,随着内存设备不断发展,空间要求降低。
小例子:有一组数,每个数都是成对出现,但是有一个数丢了,用最快的方法找出这个数。
考察到相同数字的异或为0,异或满足交换律
2、java中链表的实现
1)构建节点:
private static class Node<E> {
E item;
Node<E> next;
Node<E> prev;
Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
包含数据、前驱、后继
2)定义头结点first、尾节点last
3)常用方法
添加元素add(向尾部)
void linkLast(E e) {
final Node<E> l = last;
final Node<E> newNode = new Node<>(l, e, null);
last = newNode;
if (l == null)
first = newNode;
else
l.next = newNode;
size++;
modCount++;
}
记录尾部节点-》定义一个新的节点-》将尾节点赋值为新的节点-》如果链表是空的头节点也赋值为新的节点-》否则尾节点的next指向新的元素
删除元素remove
public boolean remove(Object o) {
if (o == null) {
for (Node<E> x = first; x != null; x = x.next) {
if (x.item == null) {
unlink(x);
return true;
}
}
} else {
for (Node<E> x = first; x != null; x = x.next) {
if (o.equals(x.item)) {
unlink(x);
return true;
}
}
}
return false;
}
从头节点开始遍历,当节点值为o的时候,把这个节点从链表中去除
以下为删除节点
E unlink(Node<E> x) {
// assert x != null;
final E element = x.item;
final Node<E> next = x.next;
final Node<E> prev = x.prev;
if (prev == null) {
first = next;
} else {
prev.next = next;
x.prev = null;
}
if (next == null) {
last = prev;
} else {
next.prev = prev;
x.next = null;
}
x.item = null;
size--;
modCount++;
return element;
}
邮箱:wangh_2@sina.com