C语言 双链表的频度排序管理

题目:

有一个双链表L,每一个节点中除有prior、data和next三个域外,还有一个访问频度域freq,在链表被起用之前,其值均初始化为零。每当进行LocateNode(L,x)运算时,令元素值为x的节点中freq域的值加1,并调整表中节点的次序,使其按访问频度的递减序列排序,以便使频繁访问的节点总是靠近表头。试写一符合上述要求的LocateNode运算的算法

分析:

当x找到当前的节点的时候,节点的freq自增1,然后和前面的pre节点的freq相比较,若当前节点的freq是大于pre的,则将两节点的数据进行交换

LocateNode函数为

bool LocateNode(Node *L,int x)
{
    Node *p=L->next;
    while(p!=NULL&&p->data!=x)//开始查找等于x的元素
        p=p->next;
    
    //当查到存在等于p的节点的时候
    if(p!=NULL)//p不等于空,说明找打了需要的数字
    {
        ++p->fre;//数字对应的频率自增
        Node *pre=p->prior;
        if(pre->data!=1000)//开始交换
        {
            while(pre->data!=1000&&pre->fre<p->fre)
            {
                pre->data=pre->data+p->data-(p->data=pre->data);//换数据
                pre->fre=pre->fre+p->fre-(p->fre=pre->fre);
                p=pre;//换节点
                pre=pre->prior;
            }
            return true;//更换成功
        }
        else
            return true;//默认就是第一个节点,就不需要往前移动了
    }
    else
        return false;//没查到,p为空
}

总体测试代码:

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
typedef struct node{
    int data;
    int fre;
    struct node *prior;
    struct node *next;
}Node;
void creat_LinkList(Node *L,int a[],int n)
{
    Node *p=L;
    for(int i=0;i<n;i++)
    {
        Node *s=(Node *)malloc(sizeof(Node));
        s->data=a[i];
        s->fre=0;
        s->next=NULL;
        s->prior=p;
        p->next=s;
        p=s;
    }
}
bool LocateNode(Node *L,int x)
{
    Node *p=L->next;
    while(p!=NULL&&p->data!=x)//开始查找等于x的元素
        p=p->next;
    
    //当查到存在等于p的节点的时候
    if(p!=NULL)//p不等于空,说明找打了需要的数字
    {
        ++p->fre;//数字对应的频率自增
        Node *pre=p->prior;
        if(pre->data!=1000)//开始交换
        {
            while(pre->data!=1000&&pre->fre<p->fre)
            {
                pre->data=pre->data+p->data-(p->data=pre->data);//换数据
                pre->fre=pre->fre+p->fre-(p->fre=pre->fre);
                p=pre;//换节点
                pre=pre->prior;
            }
            return true;//更换成功
        }
        else
            return true;//默认就是第一个节点,就不需要往前移动了
    }
    else
        return false;//没查到,p为空
}
void print(Node *L)
{
    Node *p=L->next;
    int i=0;
    while(p!=NULL)
    {
        ++i;
        printf("%d(%d)	",p->data,p->fre);
        if(i%3==0)
            printf("
");
        p=p->next;
    }
}
int main(){
    int a[]={1,8,7,3,4,6,5,2};
    int n=8;
    Node L={1000,0,NULL,NULL};
    creat_LinkList(&L, a, n);
    int b[]={1,8,8,8,8,4,5,2,1};
    for(int i=0;i<9;i++)
        LocateNode(&L, b[i]);
    printf("查找频率从大到小排序可的
");
    print(&L);
}
原文地址:https://www.cnblogs.com/oldfish123/p/13660830.html