C语言泛型链表
ListNode.h
#include <stdbool.h> #ifndef __LISTNODE_H__ #define __LISTNODE_H__ /* 链表节点 */ struct ListNode { // 任何数据类型都可以存储在此节点中 void *data; struct Node *next; }; /* 函数在链表的【开头】添加一个节点。 此函数要求添加指向数据的指针 以及数据类型的大小*/ void pushNode(struct Node** headRef, void *newData, size_t dataSize); /*在链表中查询某一个节点 headRef是链表的第一个节点 toQueryItem是要查找的项目 fptr是比较的函数 */ void * queryItem(struct Node* headRef,void *toQueryItem, bool(*fptr)(void *,void *)); /* 函数打印给定链表中的节点。使用fpitr 访问用于打印当前节点数据的函数。 注意,printf()中不同的数据类型需要不同的说明符*/ void printList(struct Node *node, void(*fptr)(void *)); #endif
ListNode.c
#include<stdio.h> #include<stdlib.h> #ifndef __LISTNODE_H__ #include "ListNode.h" #endif /* 函数在链表的【开头】添加一个节点。 此函数要求添加指向数据的指针 以及数据类型的大小*/ void pushNode(struct ListNode** headRef, void *newData, size_t dataSize) { //为节点分配内存 struct ListNode* newNode = (struct ListNode*)malloc(sizeof(struct ListNode)); //将原来的头(第一个)设为新节点的下一个 newNode->next = (*headRef); //仅引用内存地址而不复制内容 newNode->data = newData; //将新节点设为头(第一个) (*headRef) = newNode; } /*在链表中查询某一个节点 headRef是链表的第一个节点 toQueryItem是要查找的项目 fptr是比较的函数 */ void * queryItem(struct ListNode* headRef, void *toQueryItem, bool(*fptr)(void *, void *)) { struct ListNode * currentNode = headRef; while (true) { if ((*fptr)(toQueryItem, currentNode->data)) { return currentNode->data; } //到末尾则跳出循环 if (currentNode->next == NULL) { break; } currentNode = currentNode->next; } return NULL; } /* 函数打印给定链表中的节点。使用fpitr 访问用于打印当前节点数据的函数。 注意,printf()中不同的数据类型需要不同的说明符*/ void printList(struct ListNode *node, void(*fptr)(void *)) { while (node != NULL) { (*fptr)(node->data); node = node->next; } }
Goods.h
#ifndef __GOODS_H__ #define __GOODS_H__ //自定义商品结构体 typedef struct Goods { int code; char * name; char * brand; char * specifications; float price; }; //创建商品结构体 struct Goods* createGoods( int code, char * name, char * brand, char * specifications, float price); /*在链表中查询某一个节点 headRef是链表的第一个节点 toQueryItem是要查找的项目 fptr是比较的函数 */ bool goodsEqual(void *toQueryItem, void *currentItem); // 函数打印商品 void printGoods(void *g); #endif
Goods.c
#include <stdbool.h> #ifndef __GOODS_H__ #include "Goods.h" #endif //商品結構體 struct Goods* createGoods( int code, char * name, char * brand, char * specifications, float price) { //为节点分配内存 struct Goods* newGood = (struct Goods*)malloc(sizeof(struct Goods)); newGood->code = code; newGood->name = name; newGood->brand = brand; newGood->specifications = specifications; newGood->price = price; return newGood; } // 函数打印商品 void printGoods(void *g) { struct Goods * good = (struct Goods *)(g); //-表示值為空時顯示的符號,3表示占3個字符位置,用于對齊 printf("%-3d %-20s %-20s %-20s %-20f \n", good->code, good->name, good->brand, good->specifications, good->price); } /*在链表中查询某一个节点 headRef是链表的第一个节点 toQueryItem是要查找的项目 fptr是比较的函数 */ bool goodsEqual( void *toQueryItem, void *currentItem) { struct Goods * toQueryGood = toQueryItem; struct Goods * currentGood = currentItem; return toQueryGood->code == currentGood->code; }
CTest.c
// CTest.cpp : Defines the entry point for the console application. // // C语言泛型链表 #include "stdafx.h" #include<stdio.h> #include<stdlib.h> #ifndef __LISTNODE_H__ #include "ListNode.h" #endif #ifndef __GOODS_H__ #include "Goods.h" #endif //函数打印整数 void printInt(void *n) { printf(" %d", *(int *)n); } // 函数打印浮点 void printFloat(void *f) { printf(" %f", *(float *)f); } /*驱动程序测试上述功能 */ int main() { struct Node *start = NULL; int i; //创建并打印int链表 unsigned intSize = sizeof(int); int arr[] = { 10, 20, 30, 40, 50 }; for (i = 4; i >= 0; i--) pushNode(&start, &arr[i], intSize); printf("Created integer linked list is \n"); printList(start, printInt); //创建并打印浮点数链表 unsigned floatSize = sizeof(float); start = NULL; float arr2[] = { 10.1, 20.2, 30.3, 40.4, 50.5 }; for (i = 4; i >= 0; i--) pushNode(&start, &arr2[i], floatSize); printf("\n\nCreated float linked list is \n"); printList(start, printFloat); //创建并打印結構體链表 unsigned goodsSize = sizeof(struct Goods); start = NULL; struct Goods* arr3[] = { createGoods(1,"方便面","康師傅","紅燒牛肉面",5.1), createGoods(2,"方便面","康師傅","紅燒排骨面",5.2), createGoods(3,"方便面","統一","紅燒牛肉面",5.3), createGoods(4,"方便面","統一","紅燒排骨面",5.4), createGoods(5,"方便面","統一","香菇燉雞面",5.5) }; for (i = 4; i >= 0; i--) pushNode(&start, arr3[i], goodsSize); printf("\n\nCreated goods linked list is \n"); printList(start, printGoods); struct Goods* toQueryItem = arr3[3]; void * good = queryItem(start, toQueryItem, goodsEqual); printf("\n\n查詢的商品是: \n"); printGoods(good); char c; scanf_s("%c", &c); return 0; }
浙公网安备 33010602011771号