应用题
5.设有一个双链表L,每个结点中除有prior、data和next这3个域外,还有一个访问频度域freq,在链表被启用之前,其值均初始化为零。每当在链表进行一次LocateNode(L,x)运算时,令元素值为x的结点中freq域的值加1,并调整表中结点的次序,使其按访问频度的递减排列,以便使频繁访问的结点总是靠近表头。试写一符合上述要求的LocateNode运算的算法。
【正确答案】typedef struct DuLNode{
ElemType data;
int freq;
struct DuLNode * pred, *next;
} * DList;
DList locate(DList L,ElemType x) { //L是带头结点的按访问频度递减的双向链表
DList p=L一>next,q; //p为L表的工作指针,q为p的前驱,用于查找插入位置
while(p&& p一>data!=x)p=p一>next; //查找值为X的结点
if(!p) {printf("不存在所查结点\n");exit(0);}
else {
p一>freq++; //令元素值为x的结点的freq域加1
p一>next一>pred=p一>pred; //将p结点从链表上摘下
p一>pred一>next=p一>next;
q=p一>pred; //以下查找P结点的插入位置
while(q!=L&& q一>freq<p一>freq) q=q一>pred;
p一>next=q一>next;q一>next一>pred=p;//将p结点插入
p一>pred=q;q一>next=p;
}
return(p); //返回值为x的结点的指针
}
提示:在算法中先查找数据x,查找成功时结点的访问频度域增1,最后将该结点按频度递减插入链表中。
【答案解析】