设有一个双向循环链表,每个结点中除有pre,data和next三个域外,还增设了一个访问频度域freq。在链表被起用之前,频度域freq的值均初始化为零,而每当对链表进行一次LOCATE(L,x)的操作后,被访问的结点(即元素值等于x的结点)中的频度域freq的值便增1,同时调整链表中结点之间的次序,使其按访问频度非递增的次序排列,以便始终保持被频繁访问的结点总是靠近表头结点。试编写符合上述要求的LOCATE操作的程序。 |
第一行输入双向循环链表的节点数m和被访问的节点数n, 第二行输入双向循环链表各节点的值, 第三行依次输入被访问的节点。 |
输出符合上述要求的双向循环链表。 输出经过n次LOCATE后的链表。 |
7 1 a b c d e f g d |
d a b c e f g |
#include <stdio.h>
#include <stdlib.h>
typedef struct listnode {
char s;
struct listnode *next;
struct listnode *pre;
int freq;
}listnode,*linklist;
linklist create(linklist tail,char c)
{
linklist p=(linklist)malloc(sizeof(listnode));
p->s=c;
p->freq=0;
tail->next=p;
p->pre=tail;
tail=p;
return tail;
}
linklist locate(linklist l,int n,int m)
{
char c;
linklist p,q,h;
p=l->next;
int i=0;
while(1)
{
c = getchar();
if(c != ' '&&c != '\n')
{
while(p)
{
if(p->s == c)
(p->freq)++;
p = p->next;
}
p=l->next;
i++;
if(i==n) break;
}
}
for(i = 0;i < m;i++)
{
p = l->next;
h = p;
q = l->next;
while(q)
{
if(h->freq< q->freq)
{
h = q;
}
q = q->next;
}
printf("%c ",h->s);
if(h->next == NULL)
{
h->pre->next = NULL;
}
else
{
if(h->pre == NULL)
{
l = l->next;
l->pre = NULL;
}
else
{
h->next->pre = h->pre;
h->pre->next = h->next;
}
}
free(h);
}
printf("\n");
return 0;
}
int main()
{
linklist l,tail;
l=(linklist)malloc(sizeof(listnode));
l->pre=NULL;
tail=l;
int m,n;
scanf("%d%d",&m,&n);
int i = 0;
char c;
while(1)
{
c = getchar();
if(c != ' '&&c != '\n')
{
tail= create(tail,c);
i++;
if(i == m)
{
break;
}
}
}
tail->next = NULL;
locate(l,n,m);
return 0;
}