【王道数据结构】【chapter2线性表】【P43t13】

本文介绍了一种在非循环双向链表中实现Locate操作的算法,每次查找时更新元素的访问频度,保持链表中节点按访问频度递减排列,频繁访问的节点靠近表头。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

设有一头指针为L的带有表头结点的非循环双向链表,其每个结点中除有prior(前驱指针),data(数据)和next(后继指针)域外,还有一个访问频度域freq。在链表被起用前,其值均初始化为零。每当在链表中进行一次Locate(L,x)运算时,令元素值为x的结点中freq域的值增1,并使此链表中结点保持按访问频度非增(递减)的顺序排列,同时最近访问的结点排在频度相同的结点的最后,以便使频繁访问的结点总是靠近表头。试编写符合上述要求的Locate(L,x)运算的算法,该运算为函数过程,返回找到结点的地址,类型为指针型。

#include <iostream>
#include <time.h>
#include <stdlib.h>
typedef  struct node{
    int data;
    node* next;
    node* prev;
    int freq;
}node,*list;

list Init()
{
    list head=(list) malloc(sizeof (node));
    head->next= nullptr;
    head->data=-1;
    head->freq=0;
    head->prev= nullptr;
    return head;
}

list Buynewnode(int x)
{
    list tmp=new node;
    tmp->next= nullptr;
    tmp->data=x;
    tmp->freq=0;
    tmp->prev= nullptr;
    return tmp;
}

list Locate(list head,int x)
{
    list pointer=head;
    while(pointer->next){
        if(pointer->next->data==x) break;
        else pointer=pointer->next;
    }
    if(pointer->next== nullptr) return nullptr;
    pointer->next->freq++;
    list tmp=pointer;
    while(tmp!=head&&tmp->freq<=pointer->next->freq) tmp=tmp->prev;
    if(tmp==pointer) return pointer->next;//如果已经是排好的就不要再交换了。
    list t1=pointer->next->next,t2=pointer->next,t3=tmp->next;
    pointer->next=t1;
    if(t1) t1->prev=pointer;
    tmp->next=t2;
    t2->prev=tmp;
    t2->next=t3,t3->prev=t2;
    return t2;
}
int main() {
    srand(time(nullptr));
    list head=Init();
    list pointer=head;
    printf("Initian\n");
    for(int i=0;i<10;i++)
    {
        pointer->next= Buynewnode(i+1);
        pointer->next->prev=pointer;
        pointer=pointer->next;
    }

    for(pointer=head->next;pointer!= nullptr;pointer=pointer->next) {
        printf("%3d",pointer->data);
    }
    puts("");
    printf("frequency\n");

    for(pointer=head->next;pointer!= nullptr;pointer=pointer->next) {
        printf("%3d",pointer->freq);
    }
    puts("");

    printf("Input\n");

    for(int i=0;i<100;i++)
    {
        int x=rand()%10+1;
        printf("%3d",x);
        Locate(head,x);
    }
    puts("");

    printf("order\n");

    for(pointer=head->next;pointer!= nullptr;pointer=pointer->next) {
        printf("%3d",pointer->data);
    }
    puts("");

    printf("frequency\n");
    for(pointer=head->next;pointer!= nullptr;pointer=pointer->next) {
        printf("%3d",pointer->freq);
    }
    puts("");
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

桜キャンドル淵

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

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

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

打赏作者

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

抵扣说明:

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

余额充值