双向链表的访问,双向链表的排序
题目
已知不带头结点的双向链表第一个节点的指针为list,链节点除了数据域和分别指向该结点的前驱结点和后继结点的指针域外,还设置记录该节点访问次数频度域freq(初始值为0),请设计一算法LOCATE(list,x),该算法的功能是每当访问LOCATE(list,x)操作,数据域信息为X的结点freq域的值增加1,并且保持链表中结点的freq值得递减链接,使得频繁访问的结点靠近前面。
分析
思路分析:
第一步:双向链表中查找符合条件的X,并且freq+1;
第二步:根据freq的大小递减排序
假设 算法的数据域为int型。
代码
typedef struct DNode{
int data; // 数据域
int freq; // 存储访问的次数
struct DNode *llink,*rlink;
}DNode,*DLinklist;
函数的具体实现
// 双向链表的访问,双向链表的排序
int LOCATE(DLinklist list,int x){
DLinklist q,p;
p=list->rlink;
while (p!=NULL&&p->data!=x) {
p = p->rlink; // 判断指针下移
}
if (p==NULL) {
return 0; // 如果为空,说明没有和X相等的这个结点
}else {
p->freq++; // 访问的次数加一
q=p->llink; // q 指向p 所指的前驱结点
while (q!=list&&q->freq<p->freq) {
// q与p的访问次数比较 条件成立需要移动指针
p->llink=q->llink;
p->llink->rlink=p; // p所指结点移到q的前面
q->rlink=p->rlink;
if (p->rlink!=NULL) {
q->rlink->llink=q;
}
q->llink=p;
p->rlink=q; // 这里防止锻炼哦。
q=p->llink; // q指向p的前驱结点
} // while
} // if
return 1;
}