试设计一个实现下述要求的Locate运算的函数。设有一个带表头结点的双向链表L,每个结点有4个数据成员:指向前驱结点的指针prior、指向后继结点的指针next、存放数据的成员data和访问频度freq。所有结点的freq初始时都为0。每当在链表上进行一次Locate(L,x)操作时,令元素值为x的结点的访问频度freq加1,并将该结点前移,链接到与它的访问频度相等的结点后面,使得链表中所有结点保持按访问频度递减的顺序排列,以使频繁访问的结点总是靠近表头。
typedef struct OneNode{
int x;
int freq;
struct OneNode *rlink;
struct OneNode *llink;
} Node,*LinkList;
void initCircleLinkList(LinkList *linkList){
*linkList=(Node *)malloc(sizeof(Node));
(*linkList)->rlink=(*linkList);
(*linkList)->llink=(*linkList);
(*linkList)->x=-1;
(*linkList)->freq=-1;
}
/**
* 尾插法
* @param linkList
* @param x
*/
void insertTailCirCleData(LinkList linkList,int x){
Node *headNode=linkList;
Node *node= (Node *)malloc(sizeof(Node));
node->freq=0;
node->x=x;
Node *tailNode=headNode->llink;
node->llink=tailNode;
node->rlink=headNode;
headNode->llink=node;
tailNode->rlink=node;
}
/**
* 头插法
* @param linkList
* @param x
*/
void insertHeadCirCleData(LinkList linkList,int x){
Node *headNode=linkList;
Node *node= (Node *)malloc(sizeof(Node));
node->freq=0;
node->x=x;
//链表连接
Node *nextNode=headNode->rlink;
node->rlink=nextNode;
node->llink=headNode;
nextNode->llink=node;
headNode->rlink=node;
}
void printCirCleData(LinkList linkList){
Node *node=linkList->rlink;
while (node!=linkList){
printf("x->%d fre->%d\n",node->x,node->freq);
node=node->rlink;
}
}
void Locate(LinkList linkList,int x){
Node *node=linkList->rlink;
//空链表不处理
if(node==linkList){
return;
}
while (node!=linkList) {
if(node->x==x){
node->freq=node->freq+1;
break;
}
node=node->rlink;
}
//重新排序
Node *current=node;
node=node->llink;
while (node!=linkList){
//交换两个结点位置
if(node->freq<current->freq){
Node *nextNode=current->rlink;
Node *preNode=node->llink;
preNode->rlink=current;
current->llink=preNode;
node->rlink=nextNode;
nextNode->llink=node;
node->llink=current;
current->rlink=node;
node=preNode;
} else {
node=node->llink;
}
}
}
int main(){
//头结点不使用
LinkList linkList;
initCircleLinkList(&linkList);
for (int i = 0; i < 5; ++i) {
//头插法
insertTailCirCleData(linkList,i);
//尾插法
// insertHeadCirCleData(linkList,i);
}
printf("old:\n");
printCirCleData(linkList);
Locate(linkList,3);
Locate(linkList,3);
Locate(linkList,2);
Locate(linkList,2);
Locate(linkList,2);
Locate(linkList,2);
Locate(linkList,0);
Locate(linkList,0);
Locate(linkList,4);
Locate(linkList,4);
Locate(linkList,4);
printf("new:\n");
printCirCleData(linkList);
} 运行结果