代码清单

 // linkedlist.h
#ifndef __LINKEDLIST_H__
#define __LINKEDLIST_H__ #include <assert.h>
#include <malloc.h>
#include <string.h> typedef int LinkedListData; typedef struct LinkedListNode {
LinkedListData data; struct LinkedListNode * prior;
struct LinkedListNode * next;
} LinkedListNode, *LinkedList; typedef enum {
TRAVELDIR_FORWARD, TRAVELDIR_BACKWARD
} LinkedListTravelDir; LinkedList linkedlist_new();
void linkedlist_destory(LinkedList *list); void linkedlist_insert(LinkedList list, LinkedListTravelDir dir, int location,
const LinkedListData data);
void linkedlist_delete(LinkedList list, LinkedListTravelDir dir, int location);
int linkedlist_locate(const LinkedList list, LinkedListTravelDir dir,
const LinkedListData data, int (*fpCompare)(const void *, const void *));
LinkedListData * linkedlist_get(LinkedList list, LinkedListTravelDir dir,
int location);
int linkedlist_length(const LinkedList list); #endif // __LINKEDLIST_H__ // linkedlist.c
#include "linkedlist.h" LinkedList linkedlist_new() {
// alloc head node
LinkedList list = malloc(sizeof(LinkedListNode));
assert(list); // initialize head node's pointer field
list->prior = list;
list->next = list; return list;
} void linkedlist_destory(LinkedList *list) {
while (linkedlist_length(*list)) {
linkedlist_delete(*list, TRAVELDIR_FORWARD, );
}
free (*list);
*list = NULL;
} void linkedlist_insert(LinkedList list, LinkedListTravelDir dir, int location,
const LinkedListData data) {
LinkedList pCurNode = list;
assert(location > && location <= linkedlist_length(list) + ); // alloc new node
LinkedListNode * pNode = malloc(sizeof(LinkedListNode));
assert(pNode);
memcpy(&(pNode->data), &data, sizeof(LinkedListData)); // move current pointer to prior node
if (dir == TRAVELDIR_FORWARD) {
for (int i = ; i < location - ; i++, pCurNode = pCurNode->next)
; } else {
if (dir == TRAVELDIR_BACKWARD) {
for (int i = ; i < location; i++, pCurNode = pCurNode->prior)
;
}
} // insert new node
pNode->next = pCurNode->next;
pNode->prior = pCurNode;
pCurNode->next = pNode;
pNode->next->prior = pNode;
} void linkedlist_delete(LinkedList list, LinkedListTravelDir dir, int location) {
LinkedList pCurNode = list;
assert(location > && location < linkedlist_length(list) + ); // move current pointer to the node will deleted
if (dir == TRAVELDIR_FORWARD) {
for (int i = ; i < location; i++, pCurNode = pCurNode->next)
;
} else {
if (dir == TRAVELDIR_BACKWARD) {
for (int i = ; i < location; i++, pCurNode = pCurNode->prior)
;
}
} // delete current node
pCurNode->prior->next = pCurNode->next;
pCurNode->next->prior = pCurNode->prior;
free(pCurNode);
} int linkedlist_locate(const LinkedList list, LinkedListTravelDir dir,
const LinkedListData data, int (*fpCompare)(const void *, const void *)) {
static int location = ;
static LinkedList pCurNode = NULL; // if list argument is NULL, continue to start locate
if (list) {
location = ;
pCurNode = list->next;
}
assert(location && pCurNode); // locate data
while (pCurNode != list) {
if (!fpCompare(&(pCurNode->data), &data)) {
return location;
}
location++;
if (dir == TRAVELDIR_FORWARD) {
pCurNode = pCurNode->next;
} else {
if (dir == TRAVELDIR_BACKWARD) {
pCurNode = pCurNode->prior;
}
}
} return -;
} LinkedListData * linkedlist_get(LinkedList list, LinkedListTravelDir dir,
int location) {
LinkedList pCurNode = list;
assert(location > && location < linkedlist_length(list) + ); // move pointer to the node wanna get
if (dir == TRAVELDIR_FORWARD) {
for (int i = ; i < location; i++, pCurNode = pCurNode->next)
;
} else {
if (dir == TRAVELDIR_BACKWARD) {
for (int i = ; i < location; i++, pCurNode = pCurNode->prior)
;
}
} return &(pCurNode->data);
} int linkedlist_length(const LinkedList list) {
int length = ;
assert(list);
LinkedList pCurNode = list->next; while (pCurNode != list) {
length++;
pCurNode = pCurNode->next;
} return length;
}

双向循环链表(C语言描述)(三)的更多相关文章

  1. 一种神奇的双向循环链表C语言实现

    最近在看ucore操作系统的实验指导.里面提要一个双向循环链表的数据结构,挺有意思的. 其实这个数据结构本身并不复杂.在普通链表的基础上加一个前向指针,我们就得到了双向链表,再把头尾节点连起来就是双向 ...

  2. 带头结点的双向循环链表----------C语言

    /***************************************************** Author:Simon_Kly Version:0.1 Date: 20170520 D ...

  3. C++实现双向循环链表

    本次博文是关于利用C++模板的方式实现的双向循环链表以及双向循环链表的基本操作,在之前的博文C++语言实现双向链表中,已经给大家分析了双向循环链表的结构,并以图示的方式给大家解释了双向循环链表的基本操 ...

  4. 双向循环链表(C语言描述)(四)

    下面以一个电子英汉词典程序(以下简称电子词典)为例,应用双向循环链表.分离数据结构,可以使逻辑代码独立于数据结构操作代码,程序结构更清晰,代码更简洁:电子词典的增.删.查.改操作分别对应于链表的插入. ...

  5. 双向循环链表(C语言描述)(一)

    双向循环链表是链表的一种,它的每个节点也包含数据域和指针域.为了方便程序维护,可以单独为数据域定义一种数据类型,这里以整型为例: typedef int LinkedListData; 双向循环链表( ...

  6. C语言通用双向循环链表操作函数集

    说明 相比Linux内核链表宿主结构可有多个链表结构的优点,本函数集侧重封装性和易用性,而灵活性和效率有所降低.     可基于该函数集方便地构造栈或队列集.     本函数集暂未考虑并发保护. 一  ...

  7. 数据结构与算法分析——C语言描述 第三章的单链表

    数据结构与算法分析--C语言描述 第三章的单链表 很基础的东西.走一遍流程.有人说学编程最简单最笨的方法就是把书上的代码敲一遍.这个我是头文件是照抄的..c源文件自己实现. list.h typede ...

  8. (C语言版)链表(四)——实现双向循环链表创建、插入、删除、释放内存等简单操作

    双向循环链表是基于双向链表的基础上实现的,和双向链表的操作差不多,唯一的区别就是它是个循环的链表,通过每个节点的两个指针把它们扣在一起组成一个环状.所以呢,每个节点都有前驱节点和后继节点(包括头节点和 ...

  9. Jquery如何序列化form表单数据为JSON对象 C# ADO.NET中设置Like模糊查询的参数 从客户端出现小于等于公式符号引发检测到有潜在危险的Request.Form 值 jquery调用iframe里面的方法 Js根据Ip地址自动判断是哪个城市 【我们一起写框架】MVVM的WPF框架(三)—数据控件 设计模式之简单工厂模式(C#语言描述)

    jquery提供的serialize方法能够实现. $("#searchForm").serialize();但是,观察输出的信息,发现serialize()方法做的是将表单中的数 ...

  10. 1.Go语言copy函数、sort排序、双向链表、list操作和双向循环链表

    1.1.copy函数 通过copy函数可以把一个切片内容复制到另一个切片中 (1)把长切片拷贝到短切片中 package main import "fmt" func main() ...

随机推荐

  1. Xmanager连接到RedHat Enterprise Linux 6.8

    RedHat Enterprise Linux 6 配置Xmanager ,实现图形界面连接 X是用在大多数UNIX系统中的图形支持系统.如果你在你的Linux机器上使用GNOME或者KDE的话,你就 ...

  2. jmeter3.2版本完美实现Load Test报表

    今天下载了最新版的apache tomcat jmeter 3.2,需要jdk1.8以上的版本. 用非GUI模式运行压力测试后,出现的报表太完美了. 将jmx脚本放在就jmeter_home下的Scr ...

  3. 关于Client_Abort_Exception异常的分析和解决

    1.什么情况下会出现“ClientAbortException:  java.net.socketException:  Broken pipe”? 答:客户端非正常(标准握手协议)退出连接,体现在h ...

  4. 【PHP】震惊,一张图详解递归函数!!!!

    在PHP学习中,递归函数是一个非常重要也是非常难以理解的部分,本博文将通过一张图尽可能演示这个过程,不对之处还请指出

  5. Java虚拟机-----------Java内存区域与内存溢出异常

    Java内存区域划分 Java虚拟机运行时的数据区大致可划分为五部分:方法区,堆(两部分组成Java堆内存),虚拟机栈,本地方法栈(Java栈内存),程序计数器. 1.程序计数器 程序计数器占较小的内 ...

  6. java基础系列--Date类

    原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/7126930.html 1.Date类概述 Date类是从JDK1.1就开始存在的老类,其提 ...

  7. Spring 控制反转

    Spring 控制反转 具体内容 Spring 开发框架之中有几个概念DI&IOC.AOP.那么要想理解Spring就必须首先理解控制反转的核心意义是什么? 对于IOC来讲如果直接进行文字的描 ...

  8. JS弹出下载对话框以及实现常见文件类型的下载

    写在前面 JS要实现下载功能,一般都是这么几个过程:生成下载的URL,动态创建一个A标签,并将其href指向生成的URL,然后触发A标签的单击事件,这样就会弹出下载对话框,从而实现了一个下载的功能. ...

  9. MySQL-FAQ

    1.ERROR 1130: Host 'xxx' is not allowed to connect to this MySQL server远程连接mysql服务器报上述错误.解决方法:1.改表法. ...

  10. MySQl开发和生产环境索引对比

    --1.创建索引信息表create table `t_index_update` (  `table_name` varchar(20) COLLATE gbk_bin DEFAULT NULL,  ...