设头指针为L的带有表头结点的非循环双向链表,其每个结点中除有prior(前驱指针),data(数据)和next(后继指针)域外,还有一个访问频度域freq.在链表被启用前,其值均初始化为零,每当在链表中进行一次Locate(L,x)运算时,令元素值为x的结点中freq域的值增1,并使此链表中结点保持按访问频度非增(递减)的顺序排列,同时最近访问的结点排在频度相同的结点前面,以便使频繁访问的结点总是靠近表头.试编写符合上述要求的Locate(L,x)运算的算法,该运算为函数过程,返回找到结点的地址,类型为指针型.
#include<stdio.h>
#include<stdlib.h>
typedef struct DNode {
int data;
struct DNode *prior,*next;
int freq=0;
} DNode, *DLinkList;
DLinkList Locate(DLinkList &L, int x) {
DNode *p=L->next,*q;
while(p&&p->data!=x)
p=p->next;
if(!p) {
printf("不存在值为x的结点\n");
exit(0);
} else {
p->freq++;
if(p->next!=NULL) p->next->prior = p->prior;
p->prior->next = p->next;
q=p->prior;
while(q!=L && q->freq<=p->freq)
q = q->prior;
p->next = q->next;
q->next->prior = p;
p->prior=q;
q->next=p;
}
return p;
}
DLinkList CreateList_DL() {
DNode *head, *p, *s;
int x;
head = (DNode *)malloc(sizeof(DNode));
head->prior = NULL;
p=head;
printf("请输入元素(输入9999结束):\n");
scanf("%d",&x);
while(x!=9999) {
s=(DNode *)malloc(sizeof(DNode));
s->data=x;
p->next=s;
s->prior=p;
p=s;
scanf("%d",&x);
}
p->next = NULL;
return head;
}
void PrintList(DLinkList head) {
DNode *p;
p=head->next;
while(p) {
printf("%d ",p->data);
p=p->next;
}
}
int main() {
DLinkList L=CreateList_DL();
PrintList(L);
int x;
printf("\n请输入需要查找的数值:\n");
scanf("%d",&x);
DLinkList lo = Locate(L,x);
PrintList(L);
printf("\n查找的x的位置为:%d\n",lo);
}
运行结果
|