2015年09月12日

异或运算特性 a ^ b = c 则 c ^ b = a , c ^ a = b, 双向链表需要两个指针,一个指向前一个结点,一个指向后一个结点, 异或双向链表只用一个指针,该指针等于 前后两两个结点指针的异或的结果,这样节省了空间,但增加了计算。
一般的双向链表节点中包含两个指针,分别指向前驱和后继。异或指针双向链表的节点只有一个“指针”,这个指针是另外两个指针的“异或”值,并利用以下运算得到其前驱和后继的指针:

a^(a^b)=b
(a^b)^b=a

在C语言中,可以先把指针转换为无符号整型数然后进行异或,另外还应保存指向链表头尾节点的指针。

按照这种思路,节点中的这一个指针还可以是“加法”值,或者其他指针运算得到的值。如果是加法,可以利用以下运算得到其前驱和后继指针:

(x+y)-x=y
(x+y)-y=x

需要注意的是,这样的“加法”运算或“异或”运算都是针对指针的值本身的,即指针转换为无符号整型后的运算。不能跟指针运算(如两个指针相减)混淆。

异或指针双向链表的建立、遍历等参考如下实现。

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 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 //main.cpp  #include <iostream> using namespace std; #include "xorp.h" int main(int argc, char *argv[]) {     XorLinkedList list;     char value[NUM+1]="abcdef";     if(!initList(&list, value)){       cout<<"initList error\n";       exit(-1);     }     traverse(&list, 'l');//从左到右的遍历     traverse(&list, 'r');//从右到左的遍历     destroy(&list);          system("PAUSE");     return true; } //xorp.h #define NUM 6 typedef struct XorNode{     char data;     struct XorNode *LRPtr;       }XorNode, *XorPointer;   typedef struct{     XorPointer l, r;//分别指向双向链表的左端和右端 }XorLinkedList;   //异或运算 XorPointer XorP(XorPointer p, XorPointer q); //建立双向链表 bool initList(XorLinkedList *pList, char value[NUM]); //销毁链表 void destroy(XorLinkedList *pList); //遍历 void traverse(const XorLinkedList *pList, char direction);   //xorp.cpp   #include <iostream> #include "xorp.h" using namespace std;  //异或运算 XorPointer XorP(XorPointer p, XorPointer q){     return (XorPointer)((unsigned)p^(unsigned)q);          }   //建立异或指针双向链表 bool initList(XorLinkedList *pList, char value[NUM]){      if(NUM<1)        return false;              XorPointer pl, p, pr;      int i=0;            p=(XorPointer)malloc(sizeof(XorPointer));      if(!p)        return false;      pl=p;      p->data=value[i++];      pList->l=p;      pr=NULL;         for(; i<NUM; ++i){        pr=(XorPointer)malloc(sizeof(XorPointer));        if(!p)          return false;        pr->data=value[i];        p->LRPtr=XorP(pl, pr);        pl=p;        p=pr;      }      pList->r=p;      if(pr!=NULL)        p->LRPtr=XorP(pl, pr);      return true; }  //销毁异或指针双向链表 void destroy(XorLinkedList *pList){      XorPointer m, n, p;         XorPointer head=pList->l;      XorPointer tail=pList->r;            m=n=head;      cout<<"free:";      while(n!=tail){        p=XorP(m, n->LRPtr);        cout<<n->data<<" ";        free(n);//释放n指向的内容,但n的值本身不变        m=n;        n=p;      }      cout<<n->data<<" ";      free(n);      cout<<endl; } //遍历异或指针双向链表 void traverse(const XorLinkedList *pList, char direction){      XorPointer m, n, p;      XorPointer head=(direction=='l')?pList->l:pList->r;      XorPointer tail=(direction=='r')?pList->l:pList->r;            cout<<"traverse:";      m=n=head;      cout<<m->data;      while(n!=tail){        p=XorP(m, n->LRPtr);        cout<<p->data;        m=n;        n=p;      }      cout<<endl; }
上一篇:在MATLAB中使用tensorflow


下一篇:《TensorFlow+Keras自然语言处理实战》图书介绍