小白算法积累——单链表20#带头结点双链表+统计访问频度+按度&访问先后排序

题目:设头指针为L的带有表头结点的非循环双向循环链表,其每个结点中除有pred(前驱指针),data(数据)和next(后继指针)域外,还有一个访问频度域freq。
在链表被启用前,其值均初始化为0。每当在链表中进行一次Locate(L,x),运算时,令元素值为x的结点中freq域的值+1,并使此链表中结点保持按访问频度非增(递减)的顺序排列,同时最近访问的结点排在频度相同的结点前面,以便使频繁访问的结点总是靠近表头。

试编写符合上述要求的Locate(L,x)运算的算法,该运算为函数过程,返回找到结点的地址,类型为指针型。

关键字:带头结点双链表+统计访问频度+按度&访问先后排序

思路
关注:双链表的查找、删除和插入算法
保持按访问频度非增(递减)的顺序排列

1.首先在双向链表中查找数据值为X的结点,
2.查到后,将结点从链表中摘下,
3.然后再顺着结点的前驱链(双链表要灵活运用前驱链)查找该结点的插入位置
(题目要求:频度递减,且排在同频度的第一个,即向前找到第一个比它频度大的结点,插入位置为该结点之后),
4.并插入到该位置:注意步骤的顺序。指针的调配
需要变量:L,x
当前值为x的元素的工作指针p,pre为前驱指针(负责插入功能的指针)


DLinkList Locate(DLinkList &L,ElemType X){//本算法先查找数据X(用户输入x默认已经完成了),查找成功时结点的访问频度+1
//最后将该结点按频度递减插入链表中适当位置,同频度最近访问的在前面
   DNode *p=L-next,*pre;//p为工作指针,pre为前驱指针(负责查找插入位置)
   while(p&&p->data!=x)//当遍历没有结束并且没有查找到值为X的元素时
      p=p->next;//p向下遍历
   if(!p){//如果遍历结束也没找到值为x的元素
     printf("不存在值为X的结点\n")
     exit(0);
   }
   else{//如果找到了值为x的元素
      p->freq++; //当前元素的频度+1
      if(p->next!=NULL) //如果当前元素不是最后一个元素,即“后继还有人”
        p->next->pred=p->pred;  //那么将当前元素的后继元素的前驱链接到当前元素的前驱元素
      p->pred->next=p->next; //将当前元素的前驱元素的后继链接给当前元素的后继元素,以上两步完成了将当前元素摘出的功能
      pre=p->pred; //开始寻找插入位置
      while(pre!=L&&pre->freq<=p->freq) //当插入位置没有找到
           pre=pre->pred; //前驱指针继续向前寻找,直到找到(本题中此条件一定可以找到的)
      p->next=pre->next; //开始插入当前元素
      pre->next->pred=p; //
      p->pred=pre; //
      pre->next=p; //
      }
    return p;
   }
     
   }

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值