王道数据结构课后代码题p40 20.每当在链表中进行一次 Locate(L,x)运算时,令元素值为X的结点中 freq 域的值增 1,并使此链表中结点保持按访问频度非增(递减)的顺序排列,同时最近访

   

本题就是找到使用locate(L,x)的次数最高的x,并将他放到链表的最前面,同时最近访问的结点排在频度相同的结点前面

本题代码如下

linklist locate(linklist* L, int x)
{
    lnode* p = (*L)->next, * q = *L;//p为工作指针,q为p的前驱,用于插入位置
    while (p && p->data != x)//查找值为x的结点
    {
        q = p;
        p = p->next;
    }
    if (!p)//不存在值为x的结点
    {
        printf("没有这个结点\n");
        return NULL;
    }
    else
    {
        p->freq++;//令元素值为x的结点的freq域加1
        if (p->next != NULL)
            p->next->pred = p->pred;
        p->pred->next = p->next;//将p结点从链表摘下
        q = p->pred;
        while (q != *L && q->freq <= p->freq)//查找p的插入位置
            q = q->pred;
        p->next = q->next;
        if (q->next != NULL)//将p排在同频率的第一位
            q->next->pred = p;
        q->next = p;
        p->pred = q;
    }
    return p;//返回值为x的结点
}

完整测试代码

#include 
#include 
typedef struct lnode
{
    int data;
    struct lnode* next;
    struct lnode* pred;
    int freq;
} lnode, * linklist;
int n = 5;
int a[5] = { 1,2,3,4,5 };
void buildlinklist(linklist* L)
{
    *L = (lnode*)malloc(sizeof(lnode));
    (*L)->next = *L;
    (*L)->pred = NULL;
    lnode* s, * r = *L;
    int i = 0;
    for (i = 0; i < n; i++)
    {
        s = (lnode*)malloc(sizeof(lnode));
        s->data = a[i];
        s->freq = 0;
        s->next = r->next;
        if (r->next != NULL)
            r->next->pred = s;
        r->next = s;
        s->pred = r;
        r = s;
    }
    r->next = NULL;
}
linklist locate(linklist* L, int x)
{
    lnode* p = (*L)->next, * q = *L;//p为工作指针,q为p的前驱,用于插入位置
    while (p && p->data != x)//查找值为x的结点
    {
        q = p;
        p = p->next;
    }
    if (!p)//不存在值为x的结点
    {
        printf("没有这个结点\n");
        return NULL;
    }
    else
    {
        p->freq++;//令元素值为x的结点的freq域加1
        if (p->next != NULL)
            p->next->pred = p->pred;
        p->pred->next = p->next;//将p结点从链表摘下
        q = p->pred;
        while (q != *L && q->freq <= p->freq)//查找p的插入位置
            q = q->pred;
        p->next = q->next;
        if (q->next != NULL)//将p排在同频率的第一位
            q->next->pred = p;
        q->next = p;
        p->pred = q;
    }
    return p;//返回值为x的结点
}
void print(linklist* L)
{
    lnode* k = (*L)->next;
    while (k)
    {
        printf("%d ", k->data);
        k = k->next;
    }
}
int main()
{
    linklist L;
    buildlinklist(&L);
    printf("原链表为: ");
    print(&L);
    locate(&L, 5);
    locate(&L, 5);
    locate(&L, 2);
    locate(&L, 2);
    printf("\n结果链表为: ");
    print(&L);
    return 0;
}

这里5跟2都调用了两次,但是最后一次调用的是2。所以最后的结果链表里2排在5的前面

这样的话结果如下,结果链表中5就在2前面了,如下

再看一种情况

这样2被查了三次,在最前面

你可能感兴趣的:(王道课后习题单链表,数据结构,链表,算法,c语言)