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语言双向链表的表示与实现实例详解的使用技巧和注意事项,需要的朋友参考一下 1.概述: C语言中一种更复杂的链表是“双向链表”或“双面链表”。其表中的每个节点有两个连接:一个指向前一个节点,(当这个“连接”为第一个“连接”时,指向空值或者空列表);而另一个指向下一个节点,(当这个“连接”为最后一个“连接”时,指向空值或者空列表) 一个双向链表
本文向大家介绍C语言之双向链表详解及实例代码,包括了C语言之双向链表详解及实例代码的使用技巧和注意事项,需要的朋友参考一下 1,双向链表简介。 双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表。 2,例子要求: 完成双向链表的插入、删除以及查找,将
本文向大家介绍C语言实现数据结构和双向链表操作,包括了C语言实现数据结构和双向链表操作的使用技巧和注意事项,需要的朋友参考一下 数据结构 双向链表的实现 双向链表中的每一个结点都含有两个指针域,一个指针域存放其后继结点的存储地址,另一个指针域则存放其前驱结点的存储地址。 双向链表结点的类型描述: 其中,prior域存放的是其前驱结点的存储地址,next域存放的是其后继结点的存储地址。 双
本文向大家介绍C语言单向链表的表示与实现实例详解,包括了C语言单向链表的表示与实现实例详解的使用技巧和注意事项,需要的朋友参考一下 1.概述: C语言中的单向链表(单链表)是链表的一种,其特点是链表的链接方向是单向的,对链表的访问要通过顺序读取从头部开始。 链表中最简单的一种是单向链表,它包含两个域,一个信息域和一个指针域。这个链接指向列表中的下一个节点,而最后一个节点则指向一个空值。 如下图所示
本文向大家介绍C#双向链表LinkedList排序实现方法,包括了C#双向链表LinkedList排序实现方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了C#双向链表LinkedList排序实现方法。分享给大家供大家参考。具体如下: 1.函数 打印链表函数PrintLinkedList 和 排序函数SortLinkedList 注:下面代码中的链表每项都是double类型,如果换做其他
本文向大家介绍C语言单链表的实现,包括了C语言单链表的实现的使用技巧和注意事项,需要的朋友参考一下 单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。 链表结构: SList.h SList.cpp Test.cpp 以上内容是小编给大家介绍的C语言单链表的实现代码,希望对大家有所帮助!