把访问度高的放在双向链表前面

题目描述

难度:

重要性:

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

DLinkList Locate(DLinkList &L,ElemType x){
    DNode *p=L->next,*q;                   //p为工作指针,q为p的前驱,用于查找插入位置
    while(p&&p->data!=x)
        p=p->next;                         //查找值为x的结点
    if(!p)
        exit(0);                           //不存在值为x的结点
    else{
        p->freq++;                         //令元素值为x的结点的freq域加1
        if(p->pre==L||p->pre->freq>p->freq)//p是链表首结点,或freq值小于前驱
            return p;    
        //将p结点从链表上摘下
        if(p->next!=null)                   //判断p结点是否为尾结点
            p->next->pre=p->pre;            //不是 把上一结点的地址给下一节点
        p->pre->next=p->next;               //把下一结点地址交给上一结点
        q=p->pre;                           
        while(q!=L&&q->freq<=p->freq)       //查找p结点的插入位置
            q=q->pre;                       //往前移动一个结点
        p->next=q->next;
        if(q->next!=null)                    //q不是尾结点
            q->next->pre=p;                  //将p结点排在同频率的第一个
        p->pre=q;
        q->next=p;
    }
     return p;                               //返回值为x的结点的指针
}
  1. 查找是否存在要找的结点
  2. 不存在 退出
  3. 存在 freq域值加一
  4. 把该结点从链表上摘下
  5. 查找该结点的要插入的位置
  6. 将其排列在同频率的第一个
  7. 返回其地址
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值