`

(第一章 2)通用双向链表——带上下文的回调函数

 
阅读更多

编译时用的命令: gcc -g DList.c -o DList或

                gcc      DList.c -o DList

因为是c语言程序,不是c++,所以不用g++命令(否则报错)

 

#include <stdio.h>
#include <stdlib.h>

//通用双向链表
typedef int DListRet;
//ctx: 	上下文,是所有回调函数实例的公共的环境(变量)
//data: 输入参数,只被当前回调函数实例所处理
typedef DListRet (*DListVisitFunc)(void *ctx, void *data);
#define DLIST_RET_OK 1
#define DLIST_RET_STOP 2

typedef struct _DListNode{
	struct _DListNode* prev;
	struct _DListNode* next;
	void* data;
}DListNode;

typedef struct _DList{
	DListNode *first;
}DList;

//"被调用函数"(命名体现了通用型的思想)
DListRet dlist_foreach(DList *thiz, DListVisitFunc visit, void *ctx){
	DListRet ret=DLIST_RET_OK;

	DListNode *iter=thiz->first;
	while(iter!=NULL){
		ret=visit(ctx,iter->data);
		if(ret==DLIST_RET_STOP)
			break;	
		iter=iter->next;
	}

	return ret;
}

//"回调函数",由调用者提供
DListRet dlist_max(void *ctx, void *data){
	int *temp=ctx;
	if((int)data>*temp){
		*temp=(int)data;
	}

	return DLIST_RET_OK;
}

DListRet dlist_sum(void *ctx, void *data){
	long long* temp=ctx;
	*temp+=(int)data;
	//printf("%d",(int)data);
	return DLIST_RET_OK;
}

DListRet dlist_print(void *ctx, void *data){
	printf("%d\t",(int)data);
	return DLIST_RET_OK;
}

int main(){
	//初始化双向链表
	DListNode *a=(DListNode *)malloc(sizeof(DListNode));	
	DListNode *b=(DListNode *)malloc(sizeof(DListNode));
	DListNode *c=(DListNode *)malloc(sizeof(DListNode));

	a->data=(void *)2;
	b->data=(void *)5;
	c->data=(void *)3;
	
	a->next=b;
	a->prev=NULL;

	b->next=c;
	b->prev=a;

	c->prev=b;
	c->next=NULL;

	DList *list=(DList *)malloc(sizeof(DList));
	list->first=a;

	//调用
	int max=-1;
	dlist_foreach(list, dlist_max, &max);
	printf("%d\n", max);

	long long sum=0;
	dlist_foreach(list, dlist_sum, &sum);
	printf("%ld\n", sum);

	dlist_foreach(list, dlist_print, NULL);

	return 0;
}
 
分享到:
评论

相关推荐

    双向链表——1

    这是一个双向链表,非常的可以。主要有3个头文件,10多个实现文件,还有一个主函数文件,希望大家多多支持!

    通用双向链表以及内存检漏算法

    总结起来,这个项目提供了一个实际的案例,展示了如何在C语言中实现一个通用的双向链表,并结合内存检漏检测算法确保程序的资源效率。通过学习和理解这部分代码,开发者可以深化对数据结构和内存管理的理解,提高...

    通用双向链表

    通用双向链表,数据类型通用化。更高级的做法是节点话,链表节点中剥离数据,这也是软件工程中常用方法。

    双向链表及其应用——实现多项式的加法及乘法

    在乘法运算中,更复杂一些,需要对第一个多项式的每个项遍历第二个多项式,每次乘法得到的新项都加入到结果链表。这个过程类似于矩阵乘法,但每次操作的“行”和“列”都是多项式的项。 项目的测试文件可能会包含...

    C语言实现通用双向链表标准版.rar

    本资源“C语言实现通用双向链表标准版.rar”提供了一个使用C语言实现的通用双向链表实例,这对于理解和掌握数据结构,尤其是链表操作具有重要意义。 双向链表是一种线性数据结构,与单向链表不同,它允许节点在两个...

    支持类模版的C++双向链表

    总结起来,这个“支持类模版的C++双向链表”示例深入地讲解了C++中的模板机制,包括类模版和函数模版的使用,以及如何结合这些模板技术实现一个通用的双向链表。通过这个示例,我们可以更深入地理解泛型编程,以及...

    双向链表的操作

    建立一个长度为n的带头结点的双向链表,使得该链表中的数据元素递增有序排列。(必须使用双向链表完成,数据类型为整型。) Input 第一行:双向表的长度; 第二行:链表中的数据元素。 Output 输出双向链表中...

    通用链表 双向

    自己写的通用双向链表,链表数据存储不区分类型,存储均为指针,有使用事例。现在已实现的功能有链表的创建,插入(前后均可实现),单节点删除,链表...所有的删除、查找条件均使用回调函数,实现不同类型的通用存储。

    双向链表.cpp 双向链表类定义及测试代码 c++

    双向链表类定义及测试文件 对应于数据机构与算法分析(c++版)第三版或第二版 Clifford A.Shaffer 重庆大学使用教材

    java 单链表和双向链表的实现

    本话题主要探讨两种常用的数据结构——单链表和双向链表在Java中的实现,以及相关的操作,如在头部添加节点、在尾部添加节点、遍历、逆置和删除。 首先,我们来理解单链表和双向链表的基本概念。单链表是一种线性...

    Linux内核双向链表简单分析

    其中,双向链表(双链表)不仅支持向后指针,还支持向前指针,这使得双向链表在操作上更为灵活,特别是在需要频繁进行反向遍历的情况下。 #### list链表组织结构 在Linux内核中,双向链表的实现主要依赖于`struct ...

    C++经典算法 双向链表

    首先,我们需要定义双向链表的基本单元——节点。节点包含三个主要部分:数据域(data)、指向前驱节点的指针(lift)和指向后继节点的指针(right)。这里采用的是C语言的结构体定义: ```c++ typedef struct Link...

    创建双向链表_双向链表_

    相比于单向链表,双向链表在某些操作上更灵活,但也需要更多的内存来存储额外的指针。 创建双向链表通常包括以下几个步骤: 1. 定义节点结构:首先,我们需要定义一个结构体,包含数据域和两个指针域,如: ```...

    双端链表和双向链表Java代码

    本主题主要关注两种特殊类型的链表——双端链表(Double-ended LinkedList)和双向链表(Bidirectional LinkedList),并以Java语言实现为例进行讲解。 双端链表,也称为双链表,是一种允许在链表的两端进行插入和...

    stm32f103 双向链表

    在实际应用中,例如在STM32F103的中断服务程序或定时器回调中,双向链表可以用于管理任务调度、资源分配或者动态内存管理。例如,你可以创建一个任务节点,每个节点包含任务的优先级、状态和执行函数,然后用链表来...

    网上搜集的七种双向链表模板c++实现

    STL(Standard Template Library,标准模板库)提供了一种标准的双向链表容器——`std::list`。这种实现符合C++标准,兼容STL算法,并提供了丰富的操作接口。 在实际应用中,这些模板可能包含额外的功能,如反转...

    数据结构-双向链表

    双向链表,顾名思义,是一种链式存储结构,其中每个节点包含两个指针,一个指向前一个节点,另一个指向后一个节点。与单向链表相比,双向链表允许双向遍历,即可以从前往后也可以从后往前访问元素,增加了数据操作的...

    数据结构源代码之双向链表

    此函数用于在双向链表的指定位置插入一个新的节点。 ##### 7. 删除双向链表中的第i个结点 ```plaintext int DLinkListDelete(DNode *L, int i, char *elem); ``` 此函数用于删除双向链表中指定位置的节点。 #### ...

    链表——学生管理系统 MFC

    CList是一个双向链表,支持向前和向后遍历。在这个学生管理系统中,CList可以用来存储一个包含学生信息的对象,如CStudent类的实例。每个CStudent对象可能包括姓名、学号、成绩等属性。 添加功能:通过CList的...

    双向链表实现结点类

    定义、实现并测试一个双向链表结点类DNode。 链表结点类中包含私有数据成员为两个整数x,y以及左结点指针left及右结点指针right。 包含的函数成员包括: (a)对结点的数据成员赋值setDNodeValues(int,int,DNode* ...

Global site tag (gtag.js) - Google Analytics