对链表中的数据项进行访问时频度加1,保证频繁访问的结点总靠近表头。
输入输出样例:1组
#1
样例输入:
5\\表中元素个数
1 2 3 4 5\\表中元素内容
3\\一共locate3次
3\\第一次Locate 3
3\\第二次Locate 3
4\\第三次Locate 4
样例输出:
1 2 3 4 5\\原表中元素输出
3 1 2 4 5\\第一次Locate 3 后的变化
3 1 2 4 5\\第二次Locate 3 后的变化
3 4 1 2 5\\/第三次Locate 4 后的变化
//注意
//1:该程序每次运行的时间必须小于10秒,否则会超时,程序超时将不会测试剩余的测试集
//2:该程序每次运行使用的内存不能超过1M,否则会返回错误
//3:该程序每次运行输出的结果最多显示1000个字符(多余的不显示),每行末尾的所有空格用□表示
#include <iostream>
#include<stdlib.h>
using namespace std;
typedef struct dlnode
{
int data;
int freq;
struct dlnode *prior,*next;
}DLNode,*DLinkList;
DLinkList Create_List(int n);
void PrintList(DLinkList head);
void Locate(DLinkList s, int data);
int main()
{
int n;
cin>>n;
DLinkList L;
L=Create_List(n);
PrintList(L);
int m;
cin>>m;
for(int i=0;i<m;i++)
{
int x;
cin>>x;
Locate(L,x);
PrintList(L);
}
return 0;
}
void Locate(DLinkList s, int data)
{
DLNode *p, *q;
p = s->next;
q=s;
while(p && p->data != data)
{
q = p;
p = p->next;
}//找出待删结点
p->freq++;
while(q != s && q->freq < p->freq)//找出比p的频度大的结点,准备进行尾插
{
q = q->prior;
}
p->prior->next = p->next; //删除待删结点
if(p->next != NULL)
p->next->prior = p->prior;
p->next = q->next;
if(q->next != NULL)
{
q->next->prior = p;
q->next = p;
p->prior = q;
}//插入适当位置,使其freq按递增排列
}
DLinkList Create_List(int n)
{
DLinkList head;
head = (DLinkList)malloc(sizeof(DLNode));
head->next = NULL;
head->prior=NULL;
head->freq=0;
head->data = -1;
DLNode *p, *q;
p = head;
for(int i = 0; i < n; i++)
{
int x;
cin>>x;
q = (DLNode *)malloc(sizeof(DLNode));
q->data = x;
q->freq=0;
q->next = NULL;
q->prior=p;
p->next = q;
p = q;
}
return head;
}
void PrintList(DLinkList head)
{
DLinkList p=head->next;
while(p!=NULL)
{
cout<<p->data<<" ";
p=p->next;
}
cout<<endl;
}