有一双链表,每个结点中除有prior、data和next域外,还有一访问频度域freq,在链 表被启用前,其值均初始化为零。每当在链表上进行一次LOCATE(L,X)运算,元素值为x的
结点中freq域的值增1,并使此链表中结点保持按freq递减的顺序排列,以便使频繁访问的结
点总是靠近表头。设计满足上述要求的LOCATE算法
#include <iostream>
using namespace std;
int n;
typedef struct DuLNode
{
int data;
struct DuLNode* prior;
struct DuLNode* next;
int freq;
}DuLNode, * DuLinkList;
void welcome()
{
cout << "1.初始化\n";
cout << "2.输入一个循环链表\n";
cout << "3.输出\n";
cout << "4.删除\n";
cout << "0.退出\n";
cout << endl;
}
void InitList(DuLinkList& L)
{
L = new DuLNode;
L->prior = NULL;
L->next = NULL;
}
void CreatDuList(DuLinkList& L, int n)
{
L = new DuLNode;
L->prior = NULL;
L->next = NULL;
DuLNode* r;
r = L;
for (int i = 1; i <= n; i++)
{
DuLinkList p;
p = new DuLNode;
p->data = i;
p->next = L;
p->prior = r;
r->next = p;
L->prior = p;
r = p;
}
}
void display(DuLinkList& L)
{
DuLNode* p;
p = L->next;
for (int i = 0; i < n; i++)
{
cout << p->data << " ";
p = p->next;
}
}
bool LocateNode(DuLinkList h, int x)
{
DuLNode* p = h->next, * pre;
while (p != NULL && p->data != x)
p = p->next; //找data域值为x的结点p
if (p == NULL) return false; //未找到的情况
else //找到的情况
{
p->freq++; //频度+1
pre = p->prior; //结点pre为结点p的前驱结点
while (pre != h && p->freq > pre->freq)
{ //删除pre结点
p->prior = pre->prior;
pre->prior->next = p;
//将pre结点插入到p结点之后
pre->next = p->next;
if (pre->next != NULL) //若p不是尾结点
p->next->prior = pre;
pre->prior = p;
p->next = pre;
//q指向结点p的前驱结点
pre = p->prior;
}
return true;
}
}
int main()
{
DuLinkList L;
L = new DuLNode;
L->prior = NULL;
L->next = NULL;
int x;
bool a = true;
cout << "请输入链表长度!";
cin >> n;
CreatDuList(L, n);
cout << "循环链表创建成功!";
cout << endl;
cout << "链表元素为:";
display(L);
cout << endl;
while (a)
{
cout << "请输入您要访问的结点:";
cin >> x;
LocateNode(L, x);
display(L);
cout << endl;
cout << "继续请输入‘1’退出请输入‘0’! 请选择->";
cin >> a;
}
return 0;
}