C语言双向链表实现根据使用频率安排元素位置的功能实例代码

发布时间 - 2026-01-11 00:15:24    点击率:

C语言双向链表应用

前言:

平时使用音乐播放器时,播放列表中的歌曲可以很方便地进行增添,删除,去重等操作。但其本质都可以抽象成一个双向链表。为了更方便用户的使用,我认为还可以增加一个将最常播放的音乐放在播放列表的头部的功能,那么如何实现呢?

请看代码:

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int status;
typedef int elemtype;
typedef struct node{
  elemtype data;
  int freq;
  struct node * next;
  struct node * prior;
}node;
typedef struct node* dlinklist;

status visit(elemtype c){
  printf("%d ",c);
}

/*双向链表初始化*/
status initdlinklist(dlinklist * head,dlinklist * tail){
  (*head)=(dlinklist)malloc(sizeof(node));
  (*tail)=(dlinklist)malloc(sizeof(node));
  if(!(*head)||!(*tail))
    return ERROR;
  /*这一步很关键*/ 
  (*head)->prior=NULL;
  (*tail)->next=NULL;
  (*head)->freq=0;
  (*tail)->freq=0; 
  /*链表为空时让头指向尾*/
  (*head)->next=(*tail);
  (*tail)->prior=(*head);
}

/*判定是否为空*/
status emptylinklist(dlinklist head,dlinklist tail){
  if(head->next==tail)
    return TRUE;
  else
    return FALSE;
} 

/*尾插法创建链表*/ 
status createdlinklist(dlinklist head,dlinklist tail,elemtype data){
  dlinklist pmove=head,qmove=tail,pinsert;
  pinsert=(dlinklist)malloc(sizeof(node));
  if(!pinsert)
    return ERROR;
  else{
    pinsert->data=data;
    pinsert->prior=pmove;
    pinsert->next=pmove->next;
    pmove->next->prior=pinsert;
    pmove->next=pinsert;
  }
}

/*正序打印链表*/ 
status traverselist(dlinklist head,dlinklist tail){
  dlinklist pmove=head->next;
  while(pmove!=tail){
    visit(pmove->data);
    pmove=pmove->next;
  }
  printf("\n");
}

status traverselist2(dlinklist head,dlinklist tail){
  dlinklist pmove=head->next;
  while(pmove!=tail){
    visit(pmove->freq);
    pmove=pmove->next;
  }
  printf("\n");
}

/*在链表头插入元素*/
status inserthead(dlinklist head,dlinklist tail,elemtype data){
  dlinklist pinsert;
  pinsert=(dlinklist)malloc(sizeof(node));
  pinsert->data=data;
  pinsert->next=NULL;
  pinsert->prior=NULL;
  tail->prior->next=pinsert;
  pinsert->prior=tail->prior;
  pinsert->next=tail;
  tail->prior=pinsert;
  return OK;
}

/*按使用频次排序*/ 
status locateorder(dlinklist head,dlinklist tail,elemtype data){
  dlinklist pmove=head->next,qmove;
  while(pmove!=tail&&pmove->data!=data)
    pmove=pmove->next;
  if(pmove==tail){
    printf("未找到\n");
    return ERROR;
  }
  else{
    pmove->freq++;
    qmove=pmove->prior;
    while(qmove!=head&&qmove->freq<pmove->freq)//向前寻找比pmove->freq大的qmove->freq
       qmove=qmove->prior;
    if(qmove->next!=pmove){//如果找到的qmove和pmove不是直接的前驱后继关系
      pmove->next->prior=pmove->prior;
      pmove->prior->next=pmove->next;//将pmove取下
      pmove->prior=qmove;
      pmove->next=qmove->next;
      qmove->next->prior=pmove;
      qmove->next=pmove;//插到qmove之后
    }
  }
}

int main(void){
  dlinklist head,tail,pmove=head;
  int i=0;
  initdlinklist(&head,&tail);
  for(i=0;i<10;i++)
    inserthead(head,tail,i);
  printf("未经过排序的链表为\n");
  traverselist(head,tail);
  printf("在按使用频率排序后的链表为:\n"); 
  locateorder(head,tail,5);
  for(int i=0;i<3;i++){
    locateorder(head,tail,6);
  }
  traverselist(head,tail);
  printf("各元素使用频率为\n");
  traverselist2(head,tail);
}

要实现这一功能,最重要的函数是locateorder(),其实现思路是:如果某个元素的使用频率不为0,则定义一个向链表头移动的游标,寻找一个比该元素使用频率高的元素,将该元素插到找到的元素之后即可。

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!


# C语言双向链表应用  # C语言双向链表实例  # C语言算法学习之双向链表详解  # C语言类的双向链表详解  # C语言中双向链表和双向循环链表详解  # C语言数据结构 双向链表的建立与基本操作  # C语言实现数据结构和双向链表操作  # C语言 数据结构双向链表简单实例  # C语言之双向链表详解及实例代码  # C语言实现双向链表  # C语言双向链表的表示与实现实例详解  # C语言双向链表的原理与使用操作  # 链表  # 使用频率  # 为空  # 插到  # 这一  # 放在  # 还可以  # 最重要  # 播放器  # 我认为  # 希望能  # 不为  # 谢谢大家  # 但其  # 很方便  # 更方便  # 取下  # 将该  # 如何实现  # 最常 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: Laravel怎么定时执行任务_Laravel任务调度器Schedule配置与Cron设置【教程】  Laravel如何配置任务调度?(Cron Job示例)  如何挑选高效建站主机与优质域名?  在线制作视频的网站有哪些,电脑如何制作视频短片?  如何在Windows 2008云服务器安全搭建网站?  Laravel API路由如何设计_Laravel构建RESTful API的路由最佳实践  使用PHP下载CSS文件中的所有图片【几行代码即可实现】  Laravel如何优化应用性能?(缓存和优化命令)  Laravel如何使用Service Provider注册服务_Laravel服务提供者配置与加载  如何快速搭建自助建站会员专属系统?  PHP的CURL方法curl_setopt()函数案例介绍(抓取网页,POST数据)  laravel服务容器和依赖注入怎么理解_laravel服务容器与依赖注入解析  SQL查询语句优化的实用方法总结  手机钓鱼网站怎么制作视频,怎样拦截钓鱼网站。怎么办?  如何用好域名打造高点击率的自主建站?  韩国网站服务器搭建指南:VPS选购、域名解析与DNS配置推荐  如何在宝塔面板中修改默认建站目录?  javascript和jQuery中的AJAX技术详解【包含AJAX各种跨域技术】  Laravel如何使用Gate和Policy进行授权?(权限控制)  Laravel如何处理CORS跨域请求?(配置示例)  微信小程序 scroll-view组件实现列表页实例代码  Laravel如何使用集合(Collections)进行数据处理_Laravel Collection常用方法与技巧  php结合redis实现高并发下的抢购、秒杀功能的实例  Linux虚拟化技术教程_KVMQEMU虚拟机安装与调优  佛山网站制作系统,佛山企业变更地址网上办理步骤?  Laravel如何使用withoutEvents方法临时禁用模型事件  合肥制作网站的公司有哪些,合肥聚美网络科技有限公司介绍?  Laravel如何处理文件上传_Laravel Storage门面实现文件存储与管理  Win11摄像头无法使用怎么办_Win11相机隐私权限开启教程【详解】  如何在 Telegram Web View(iOS)中防止键盘遮挡底部输入框  Laravel如何使用Guzzle调用外部接口_Laravel发起HTTP请求与JSON数据解析【详解】  MySQL查询结果复制到新表的方法(更新、插入)  Laravel怎么使用Collection集合方法_Laravel数组操作高级函数pluck与map【手册】  Laravel怎么生成二维码图片_Laravel集成Simple-QrCode扩展包与参数设置【实战】  如何自定义建站之星模板颜色并下载新样式?  Windows10怎样连接蓝牙设备_Windows10蓝牙连接步骤【教程】  Laravel怎么调用外部API_Laravel Http Client客户端使用  百度浏览器网页无法复制文字怎么办 百度浏览器复制修复  Laravel如何使用Eloquent ORM进行数据库操作?(CRUD示例)  Laravel如何操作JSON类型的数据库字段?(Eloquent示例)  Laravel如何优雅地处理服务层_在Laravel中使用Service层和Repository层  如何快速重置建站主机并恢复默认配置?  Claude怎样写约束型提示词_Claude约束提示词写法【教程】  悟空识字怎么关闭自动续费_悟空识字取消会员自动扣费步骤  手机软键盘弹出时影响布局的解决方法  如何快速选择适合个人网站的云服务器配置?  JavaScript如何操作视频_媒体API怎么控制播放  七夕网站制作视频,七夕大促活动怎么报名?  laravel怎么为应用开启和关闭维护模式_laravel应用维护模式开启与关闭方法  HTML5打空格有哪些误区_新手常犯的空格使用错误【技巧】