链表节点本身只存储一个指针,可以用于节省内存(但是 Python、Java 需要建立节点 id 映射,就达不到目的了)
代码示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 #include <assert.h> #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct { int Value; uintptr_t Xor; } Node; Node* CreateNode (int value) { Node* node = malloc (sizeof (*node)); memset (node, 0 , sizeof (*node)); node->Value = value; return node; } typedef struct { Node* begin; Node* end; } LinkedList; void Append (LinkedList* l, int value) { if (l->end == NULL ) { assert(l->begin == NULL ); l->end = CreateNode(value); l->begin = l->end; } else { Node* node = CreateNode(value); node->Xor = (uintptr_t ) l->end; l->end->Xor ^= (uintptr_t ) node; l->end = node; } } Node* NextNode (Node* node, uintptr_t * pre) { Node* next = (Node*) (node->Xor ^ *pre); *pre = (uintptr_t ) node; return next; } int main () { LinkedList l = {0 }; for (int x = 5 ; x <= 10 ; x++) { Append(&l, x); } uintptr_t pre = 0 ; for (Node* iter = l.begin; iter; iter = NextNode(iter, &pre)) { printf ("%d\n" , iter->Value); } return 0 ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 #include <iostream> struct Node { int Value; uintptr_t Xor; explicit Node (int v) noexcept : Value(v), Xor(0 ) { } }; struct LinkedList { Node* begin = nullptr ; Node* end = nullptr ; LinkedList () = default ; LinkedList (const LinkedList&) = delete ; LinkedList& operator =(const LinkedList&) = delete ; LinkedList (LinkedList&& other) noexcept : begin (other.begin), end (other.end) { other.begin = other.end = nullptr ; } LinkedList& operator =(LinkedList&& other) noexcept { if (this != &other) { this ->~LinkedList (); begin = other.begin; end = other.end; other.begin = other.end = nullptr ; } return *this ; } ~LinkedList () { uintptr_t prev = 0 ; Node* curr = begin; while (curr) { uintptr_t curr_addr = reinterpret_cast <uintptr_t >(curr); uintptr_t next_addr = curr->Xor ^ prev; Node* next = reinterpret_cast <Node*>(next_addr); delete curr; prev = curr_addr; curr = next; } begin = end = nullptr ; } void Append (int value) { if (end == nullptr ) { Node* n = new Node (value); begin = end = n; } else { Node* n = new Node (value); n->Xor = reinterpret_cast <uintptr_t >(end); end->Xor ^= reinterpret_cast <uintptr_t >(n); end = n; } } template <typename Fn> void ForEach (Node* begin, Fn fn) const { uintptr_t prev = 0 ; Node* curr = begin; while (curr) { fn (curr->Value); uintptr_t curr_addr = reinterpret_cast <uintptr_t >(curr); uintptr_t next_addr = curr->Xor ^ prev; Node* next = reinterpret_cast <Node*>(next_addr); prev = curr_addr; curr = next; } } }; int main () { LinkedList l; for (int x = 5 ; x <= 10 ; ++x) { l.Append (x); } l.ForEach (l.end, [](int v) { std::cout << v << "\n" ; }); return 0 ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 package mainimport ( "fmt" "unsafe" ) type Node struct { Value int Xor uintptr } type LinkedList struct { begin *Node end *Node } func CreateNode (value int ) *Node { return &Node{Value: value} } func (l *LinkedList) Append(value int ) { if l.end == nil { node := CreateNode(value) l.begin = node l.end = node } else { node := CreateNode(value) node.Xor = uintptr (unsafe.Pointer(l.end)) l.end.Xor ^= uintptr (unsafe.Pointer(node)) l.end = node } } func NextNode (node *Node, pre *uintptr ) *Node { nextPtr := node.Xor ^ *pre *pre = uintptr (unsafe.Pointer(node)) if nextPtr == 0 { return nil } return (*Node)(unsafe.Pointer(nextPtr)) } func main () { var l LinkedList for x := 5 ; x <= 10 ; x++ { l.Append(x) } var pre uintptr = 0 for iter := l.end; iter != nil ; iter = NextNode(iter, &pre) { fmt.Println(iter.Value) } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 from typing import Any , Generator, Literal class Node : __slots__ = ("value" , "xor" ) def __init__ (self, value ): self .value = value self .xor = 0 class XorLinkedList : def __init__ (self ): self .begin = None self .end = None self ._nodes = {} def _store (self, node ): self ._nodes[id (node)] = node def append (self, value ): if self .end is None : node = Node(value) self ._store(node) self .begin = node self .end = node else : node = Node(value) self ._store(node) node.xor = id (self .end) self .end.xor ^= id (node) self .end = node def _next_node (self, node, prev_id ) -> tuple [None , Literal [0 ]] | tuple [Any , int ]: next_id = node.xor ^ prev_id if next_id == 0 : return None , 0 nxt = self ._nodes.get(next_id) if nxt is None : raise RuntimeError("corrupt xor list or node reclaimed" ) return nxt, id (node) def iter_values (self, begin: Node | None ) -> Generator[Any , Any , None ]: prev_id = 0 node = begin while node is not None : yield node.value node, prev_id = self ._next_node(node, prev_id) if __name__ == "__main__" : l = XorLinkedList() for x in range (5 , 11 ): l.append(x) for v in l.iter_values(l.end): print (v)
Reference Programming Party Tricks