这道题大概思路为,建立一个双向链表,每个结点多加一个freq域。创建一个locate函数,循环调用n次。最后用一个反向冒泡排序将链表输出。
话不多说上代码:
#include <stdio.h>
#include <stdlib.h>
typedef struct DNode
{
char data;
int freq;//多增加;了一个freq域
struct DNode *pre,*next;
}DNode,*DoubleList;
void input (char *ep)//整个创建链表函数的精髓
{
scanf(" %c",ep);
}
void CreateLink(DoubleList *l,int n,void(*input)(char*))//尾插法建立双链表
{
DoubleList p,s;
p=*l=(DoubleList)malloc(sizeof(DNode));
(*l)->pre=(*l)->next=NULL;
for(;n>0;n--)
{
s=(DoubleList)malloc(sizeof(DNode));
input(&s->data);
s->freq=0;//所有freq初始化为0
//printf("%c ",s->data);//检测插入成功
s->next=NULL;
p->next=s,s->pre=p,p=s;
}
}
void InitList(DoubleList *l)//初始化链表的函数
{
*l=(DoubleList)malloc(sizeof(DNode));
(*l)->pre=(*l)->next=NULL;
}
int chazhao(DoubleList l,char x)//查找已知元素在链表中的位置
{
DoubleList p;
int i=1;
p=l;
while(p->next!=NULL&&p->data!=x)
{
p=p->next;
i++;
}
if(p->next==NULL) return 0;//没找到返回0
return i;//找到了返回位置
}
int LOCATE(DoubleList l,char x)
{
DoubleList p;
p=l;
int k;
k=chazhao(p,x);
if(k==0) return 0;//元素不在链表里返回0
while(k>1)
{
p=p->next;
k--;
}
p->freq++;
return 1;//成功返回1
}
int main()
{
DoubleList l;
int m,n;
scanf("%d%d",&m,&n);
InitList(&l);
CreateLink(&l,m,input);
while(n>0)
{
char x;
scanf(" %c",&x);
LOCATE(l,x);
n--;
}
char t;int g;//交换的中间变量
DoubleList p,a;
a=l;
while(a->next!=NULL) a=a->next;//定义一个指向链表结尾的指针
/*p=l->next;
while(p!=NULL)
{
printf("%d ",p->freq);
p=p->next;
}检测locate后的各个freq值*/
for(int i=0;i<m-1;i++)
for(p=a;p->pre!=l;p=p->pre)
{
if(p->freq>p->pre->freq)
{
t=p->data;
p->data=p->pre->data;
p->pre->data=t;
g=p->freq;
p->freq=p->pre->freq;
p->pre->freq=g;
}//p的freq于data同时交换
/*DoubleList k;
k=l->next;
while(k!=NULL)
{
printf("%c ",k->data);
k=k->next;
if(k==NULL) printf("\n");
}//每次循环输出一边结果*/
}
p=l->next;
while(p!=NULL)
{
printf("%c ",p->data);
p=p->next;
}
return 0;
}
里面有一些检测函数我都注释掉了。再codeblocks上面跑了几遍结果都没问题,但是再noj上wa。可能是我太菜了吧。