双向链表的运用
问题描述:
假设在算法描述语言中引入指针的二元运算“异或”若a和b为指针,则a异或b的运算结果仍为原指针类型,且
A异或(a异或b)=(a异或a)异或b=b;
(A异或b)异或b=a异或(a异或b)=a;
即可利用一个指针域来实现双向链表L。链表L中的每个结点只含两个域:data域和LRPtr域,其中LRPtr域存放该节点的左邻与右邻结点指针(不存在是为null)的异或。若设指针L.Left指向链表中的最左结点,L.Right指向链表中的最右结点,则可实现从左向右或从右向左遍历此双向链表的操作。试写一算法按任一方向依次输出链表中的各元素的值。
问题分析:感觉有点回到高中时期,哪个时候,没做过的题,第一次看到都看不懂题目要问的意思,不知道它要我干什么,这是很槽糕的,通常在这样的情况下,也只有先看下答案,然后慢慢再理解一下题目的意思,这样弄懂了以后,下次碰到这样的题也就有了思路,现在又何尝不是这样呢?要弄懂是要花功夫的,过去的大学,你是怎么上的,你怎么能没有这些努力,好吧,回到正题,再想想,看书上已经给了一些提示了:
异或指针双向链表类型和指针异或函数定义为:
Typedef struct XorNode{
Char data;
Struct XorNode LRPtr;
}XorNode,*XorPointer;
Typedef struct {//无头结点的异或指针双向链表
XorPointer Left, Right;//分别指向链表的左端和右端
} XorLinkedList;
XorPointer XorP(XorPointer p,XorPointer q);//指针异或函数XorP返回指针p和q的异或的值
Status TraversingLinkList(XorLinkedList &L,char d)
{
XorPointer p,left,right;
If(d==’l’||d==’L’)
{
P=L.left;
Left=null;
While(p!=null)
{
VisitingData(p->data);
Left=p;
P=XorP(left,p->LRPtr);
}
}
Else
If(d==’R’||d==’r’)
{
P=L.right;
Right=null;
While(p!=null)
{
VisitingData(p->data);
Right=p;
P=XorP(p->LRPtr, Right);
}
}
}
接着采用上述的存储结构,写出在第i个结点之前插入一个结点的算法,和删除第i个结点的算法。
此两个算法书上都有提及,改装下
先定位:
返回的应该是地址,用指针保存,再这里函数返回的是指针类型的该怎样表示了,
暂且按我的理解来吧
Char * GetElemP_Dul(XorLinkedList &L,int i)
{
Char *p;
P=L->next;j=1;
While(p&&j<i)
{
P=p->next;
++j;
}
If(!p||j>i) return error;
Return p;
}
插入的算法:
Status ListInsert_Dul(XorLinkedList &L,int i,char d)
{
If(!(p=GetElemP_Dul(L,i)))
Return error;
If(!(s=(XorLinkedList)malloc(sizeof(XorNode)) )) return error;
S->data=d;
S->prior=p->prior; p->prior->next=s;
S->next=p;p->prior=s;
Return ok;
}
删除的算法:
Status ListDelete_Dul(XorLinkedList &L,int i)
{
If(!(p=GetElemP_Dul(L,i)))
Return error;
p->prior->next=p->next;
P->next->prior=p->prior;
Free(p);
Return ok;
}