新文章 网摘 文章 随笔 日记

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;
}

 

 

https://gist.github.com/meylingtaing/11018042

posted @ 2021-07-20 14:23  岭南春  阅读(246)  评论(0)    收藏  举报