设有一个双向循环链表,每个结点中除有pre,data和next三个域外,还增设了一个访问频度域freq。在链表被起用之前,频度域freq的值均初始化为零,而每当对链表进行一次Locate(x)的操作后

设有一个双向循环链表,每个结点中除有pre,data和next三个域外,还增设了一个访问频度域freq。在链表被起用之前,频度域freq的值均初始化为零,而每当对链表进行一次Locate(x)的操作后,被访问的结点(即元素值等于x的结点)中的频度域freq的值便增1,同时调整链表中结点之间的次序,使其按访问频度非递增的次序顺序排列,以便始终保持被频繁访问的结点总是靠近表头结点。试编写符合上述要求的Locate操作的算法。

#include <stdio.h>
#include <stdlib.h>

#define OK 1
#define ERROR 0

typedef int Status;
typedef int ElemType;

typedef struct DuLNode
{
    int freq;
    ElemType data;
    struct DuLNode *pre;
    struct DuLNode *next;
} DuLNode,*DulLinkList;

Status Locate(DulLinkList &L,ElemType e);
Status CreateList(DulLinkList &L,int n,ElemType Data[]);
Status OutputDul(DulLinkList &L);

int main()
{
    DulLinkList L;

    ElemType data[10] = {1,2,3,4,5,6,7,8,9,10};
    ElemType temp[10] = {1,8,6,2,3,4,8,5,8,9};

    CreateList(L,10,data);
    printf("原表:\n");
    OutputDul(L);

    for(int i = 1; i <= 10; i++)
        Locate(L,temp[i - 1]);
    printf("\n操作后:\n");
    OutputDul(L);
    printf("\n访问次数:\n");
    for(DulLinkList p = L->next; p != L; p = p->next)
        printf("%2d ",p->freq);
    return 0;
}

Status Locate(DulLinkList &L, ElemType x)
{
    DulLinkList p,pre;
    int i = 1;

    if(!L || L->next == L)
        return 0;
    pre = L;
    p = L->next;
    while(p != L && p->data != x)
    {
        i++;
        pre = p;
        p = p->next;
    }
    if(p != L)
    {
        p->freq++;

        while(pre != L && pre->freq < p->freq)
        {
            i--;
            pre = pre->pre;
        }

        if(pre->next != p)
        {
            p->next->pre = p->pre;
            p->pre->next = p->next;

            p->next = pre->next;
            p->pre = pre;
            pre->next->pre = p;
            pre->next = p;
        }
        return i;
    }
    return 0;
}

Status CreateList(DulLinkList &L, int n, ElemType Data[])
{
    DulLinkList s,p;
    int i;

    L = (DulLinkList)malloc(sizeof(DuLNode));
    if(!L)
        return ERROR;
    L->next = L->pre = L;

    for(i = 1,p = L; i <= n; i++,p = p->next)
    {
        s = (DulLinkList)malloc(sizeof(DuLNode));
        if(!s)
            return ERROR;

        s->data = Data[i-1];
        s->freq = 0;

        s->next = L;
        s->pre = p;
        p->next = s;

        if(p == L)
            p->pre = s;

    }
    return OK;
}

Status OutputDul(DulLinkList &L)
{
    DulLinkList p;

    if(!L)
        return ERROR;
    else
    {
        p = L->next;
        while(p != L)
        {
            printf("%2d ",p->data);
            p = p->next;
        }
    }
    return OK;
}

 

a0c29e5c19f170000f8dc87f9c5fc30d.png

 

 

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

浮央乜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值