time_limit |
3000MS |
memory_limit |
10000KB |
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 DNode{
char c;
struct DNode *llink;
struct DNode *rlink;
int freq;
//int turn;
}DNode,*PDNode;
typedef struct DList{
PDNode head,tail;
}DList,*PDList;
PDList init_dlist(int m,char *s)
{
int i;
PDNode pl,pr,pn;
PDList plist;
plist=(PDList)malloc(sizeof(DList));
plist->head=pl=(PDNode)malloc(sizeof(DNode));
plist->tail=pr=(PDNode)malloc(sizeof(DNode));
pl->rlink=pl->llink=pr; //创建循环双链表,头节点和尾节点,并不存储数据
pr->llink=pr->rlink=pl;
for(i=0;i<m;i++){
pn=(PDNode)malloc(sizeof(DNode));
//scanf("%c",&pn->c); //出现bug,会读进 " \n "
pn->c=s[i];
pn->llink=pl;
pn->rlink=pr;
pl->rlink=pn;
pr->llink=pn;
pl=pl->rlink;
pn->freq=0;
//pn->turn=i;
}
return plist;
}
void locate(PDList plist,char *s,int m,int n)
{
int i;
char a,t;
PDNode pn,pend,pbegin,pi,pj;
pn=plist->head->rlink;
for(i=0;i<n;i++){
a=s[i];
while(pn->c!=a){
pn=pn->rlink;
}
pn->freq++;
}
//下面开始排序,以结构体中turn的大小作为freq相同时顺序的标准
/****
for(pi=pn->llink;pi->freq<=pn->freq;pi=pi->llink); //从pn这个节点开始往前找与t他freq相同的节点的最左边节点 的前一个节点
pi=pi->rlink;
if(pi==pn)continue; //pi即与他freq相同的最左边的节点
for(pj=pi;pj->freq==pi->freq;pj=pj->rlink); //pj即与他freq相同的最右一个节点
pj=pj->llink;
for(;pn->turn>pi->turn;pi=pi->rlink)if(pi==pj){ //在pi和pj间找到pn所要插入的位置
pi=pi->rlink;
break; }
pi=pi->llink;
pn->llink->rlink=pn->rlink,pn->rlink->llink=pn->llink;
pn->llink=pi,pn->rlink=pi->rlink,pi->rlink->rlink=pn,pi->rlink=pn; //pn插入目标位置
}
*******/
/*******
下列算法为:选择排序
新建两个节点,将原有链表重新连接,原有链表置空
找m轮,每轮中freq最大的记录再pj中,连接至新链表上
******/
DNode dnhead,dntail;
dntail=*(plist->tail);
dnhead=*(plist->head);
PDNode phead=&dnhead,ptail=&dntail;
phead-> rlink=plist->head->rlink;
plist-> head->rlink->llink=phead;
ptail->llink=plist->tail->llink;
plist->tail->llink->rlink=ptail;
plist->head->rlink=plist->head->llink=plist->tail;
plist->tail->rlink=plist->tail->llink=plist->head;
pn=plist->head;
for(i=0;i<m;i++){
pj=pi=phead->rlink;
for(pi=phead->rlink;pi!=ptail;pi=pi->rlink){
if(pj->freq<pi->freq)pj=pi;
}
pj->llink->rlink=pj->rlink;
pj->rlink->llink=pj->llink;
//插入pj
pn->rlink=plist->tail->llink=pj;
pj->llink=pn,pj->rlink=plist->tail;
pn=pn->rlink;
}
}
void show(PDList plist)
{
PDNode pn,pend;
pn=plist->head->rlink;
pend=plist->tail;
while(pn!=pend){
printf("%c ",pn->c);
pn=pn->rlink;
}
printf("\n");
}
int main()
{
int m,n,i;
char s1[100],s2[100],c;
scanf("%d%d",&m,&n);
//fflush(stdin);
for(i=0;i<m;i++){
c=getchar();
//if(i!=0||i!=m-1)scanf(" ");
scanf("%c",&s2[i]);
}
PDList plist;
plist=init_dlist(m,s2);
//fflush(stdin);
for(i=0;i<n;i++){
c=getchar();
//if(i!=0||i!=n-1)scanf(" ");
scanf("%c",&s1[i]);
}
locate(plist,s1,m,n);
show(plist);
return 0;
}