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