问题描述:按访问频度非递增有序的带头节点的双向链表检索关键字为x的节点。对该访问频度计数,并维护该链表有序。若为找到,则插入该节点。所有节点频度初值在建表时都为零。
代码如下:
#include <stdio.h>
#include <stdlib.h>
typedef struct doublenode
{
char key;
int freq;
struct doublenode *pre,*next;
} DoubleLinkNode,*DoubleLinkList;
DoubleLinkList loc(DoubleLinkList head, char x)
{
DoubleLinkList p,q;
p = head->next;
head->key = x;
while(p->key != head->key) p = p->next;
if(p == head) //找不到关键字的节点 。新建个节点插在头结点前面
{
q = (DoubleLinkList)malloc(sizeof(DoubleLinkNode));
q->key = x;
q->freq = 0;
q->next = p;
q->pre = p->pre ;
p->pre->next = q;
p->pre = q;
}
else
{
q = p;
q->freq++;
head->freq = q->freq;// head指针的频度要修改,否则下面的while跳不出去
while(q->freq > p->pre->freq) p = p->pre;//找到当前q应该存放在的位置。p始终指向链表中比当前q频度小的最前面指针
if(p != q)
{
//先断开q
q->pre->next = q->next;
q->next->pre = q->pre;
//再把q挂到p前面
q->next = p;
q->pre = p->pre;
p->pre->next = q;
p->pre = q;
}
}
printf("\nfinally:");
p = head->next;
while(p != head)
{
printf("(%c,%d)",p->key,p->freq);
p = p->next;
}
return head;
}
DoubleLinkList createdoublelinklist(char c[],int r[],int n)
{
DoubleLinkList head,p,q;
int i;
head = (DoubleLinkList)malloc(sizeof(DoubleLinkNode));
head->next = head;
head->pre = head;
p = head->next;
if(n>0)
{
for(i = 0; i < n; i++)
{
while(p->next != head) p = p->next;
q = (DoubleLinkList)malloc(sizeof(DoubleLinkNode));
q->key = c[i];
q->freq = r[i];
q->pre = p;
q->next = p->next;
p->next->pre = q;
p->next = q;
}
}
printf("original:");
p = head->next;
while(p != head)
{
printf("(%c,%d)",p->key,p->freq);
p = p->next;
}
return head;
}
int main()
{
DoubleLinkList head;
char x,c[5]={'a','b','c','d','e'};
int r[5] = {5,3,3,2,1};
head = createdoublelinklist(c,r,5);
loc(head,'a');
loc(head,'f');
loc(head,'c');
return 0;
}