在C语言中,对于相同操作的链表,写多个寒暑进行操作很麻烦,我自定义了一个结构和一组宏定义,来实现不同链表的共性操作。 //--数据结构定义-- #pragma pack(1)//字节对齐 typedef struct { char buff[1024]; int length; }ElementType; typedef struct dlist /* 双向串列结构声明 */ { char key[20]; ElementType data; /* 节点资料 */ struct dlist *next; /* 指向下一节点的指标 */ struct dlist *last; /* 指向最后一节点的指针 */ }LinkedList; #pragma pack()//恢复原来状态 其中,数据元素ElementType类型等等,可以随意指定。 //添加数据包到链表末尾 linkedlist_put(__ptr, __struct, __key, __value) //得到指定标号的节点 linkedlist_get(__ptr, __struct, __index, __ElementType, __value) //删除指定序号的节点 linkedlist_remove(__ptr, __struct, __index) 说明: 1、__ptr,为链表头节点指针的地址 2、__struct,是结构体名称 3、__index,是节点的顺序号 4、__ElementType,为欲添加数据报的数据类型/数据类型 5、__value,__ElementType数据指针 #ifndef _MYMMSC_UTIL_LINKEDLIST_H_ /* 防止该头文件被重复引用 */ #define _MYMMSC_UTIL_LINKEDLIST_H_ ////////////////////////////////////////////////////////////////////////////////////////// #include #include #include /*包含动态内存分配函数的头文件*/ ////////////////////////////////////////////////////////////////////////////////////////// /*--链表的打印,可以根据不同的数据结构自行调整--*/ #define linkedlist_print(__ptr, __struct) \ ({ \ __struct *__p = __ptr; \ int i = 0; \ while(__p != NULL) \ { \ printf("[NO.= %d, %s]", i, __p->data.buff); \ __p = __p->next; \ i++; \ } \ printf("\n"); \ }) #define __linkedlist_create(__struct, __ptr, __n) \ ({ \ __struct *p, *L; \ int i; \ L = (__struct *)malloc(sizeof(__struct)); \ __ptr = L; \ L->next = NULL; \ for (i = __n; i > 0; --i) \ { \ p = (__struct *)malloc(sizeof(__struct)); \ p->data =rand()%200; \ p->next = L->next; \ L->next = p; \ } \ }) #define linkedlist_create(__struct, __ptr, __n) __linkedlist_create(__struct, *__ptr, __n) /* push数据到单链表 */ #define __linkedlist_put(__ptr, __struct, __key, __value) \ ({ \ __struct *__P, *__L; \ __P = (__struct *)malloc(sizeof(__struct)); \ memset(__P->key, 0x00, sizeof(__P->key)); \ strncpy(__P->key, __key, sizeof(__P->key)); \ memcpy((char*)&__P->data, (char*)&__value, sizeof(__P->data)); \ __P->next = NULL; \ if(__ptr == NULL) \ { \ __ptr = __P; \ __ptr->next = NULL; \ } \ else \ { \ __P->next = __ptr->last->next; \ __ptr->last->next = __P; \ __ptr->last->last = __P; \ } \ __ptr->last = __P; \ }) #define linkedlist_put(__ptr, __struct, __key, __value) __linkedlist_put(*__ptr, __struct, __key, __value) /*得到链表h中第i个结点*/ #define linkedlist_get(__ptr, __struct, __index, __ElementType, __value) \ ({ \ __struct *__p = NULL, *__find = NULL; \ int __j = 0; \ __p = __ptr; \ while((__p->next != NULL) && __j < (__index - 1)) \ { \ __p = __p->next; \ __j++; /*寻找第i-1个结点,p指向其前驱*/ \ } \ if(__index != 0 && (__j != __index-1 || __p->next == NULL)) \ { \ /*删除位置错误!*/ \ memset(__value, 0x00, sizeof(__ElementType)); \ } \ else \ { \ if(__index <= 0) /* 头结点 */ \ { \ memcpy(__value, (char *)&__p->data, sizeof(__ElementType)); \ } \ else \ { \ memcpy(__value, (char *)&__p->next->data, sizeof(__ElementType)); \ } \ } \ }) /* remove单链表一个节点数据 */ #define __linkedlist_remove(__ptr, __struct, __index) \ ({ \ __struct *__p = NULL, *__find = NULL; \ int __j = 0; \ __p = __ptr; \ while((__p->next != NULL) && __j < (__index - 1)) \ { \ __p = __p->next; \ __j ++; /*寻找第i-1个结点,p指向其前驱*/ \ } \ if(__index != 0 && (__j != __index-1 || __p->next == NULL)) \ { \ /*printf("Error!\n"); /*删除位置错误!*/ \ } \ else \ { \ if(__index <= 0) /* 头结点 */ \ { \ __find = __p; \ if(__p->next != NULL) \ { \ __p = __p->next; \ __p->last = __find->last; \ } \ else /* 链表即将被清空 */ \ { \ __p = NULL; \ } \ __ptr = __find->next; \ } \ else \ { \ __find = __p->next; \ if(__p->next->next != NULL) \ { \ __p->next = __p->next->next; \ } \ else /* 最后一个节点 */ \ { \ __p->next = NULL; \ } \ } \ free(__find); /*释放被删除结点空间*/ \ __find = NULL; \ } \ }) #define linkedlist_remove(__ptr, __struct, __index) __linkedlist_remove(*__ptr, __struct, __index) ////////////////////////////////////////////////////////////////////////////////////////// //--数据结构定义-- #pragma pack(1)//字节对齐 typedef struct { char buff[1024]; int length; }ElementType; typedef struct dlist /* 双向串列结构声明 */ { char key[20]; ElementType data; /* 节点资料 */ struct dlist *next; /* 指向下一节点的指标 */ struct dlist *last; /* 指向最后一节点的指针 */ }LinkedList; #pragma pack()//恢复原来状态 ////////////////////////////////////////////////////////////////////////////////////////// #endif /* _MYMMSC_UTIL_LINKEDLIST_H_ */
|