本文将介绍使用C中关键字struct 定义结构体实现单链表。
在C语言中,结构体的自引用只能通过指针来实现,因为在系统中指针的大小是固定(32位系统时大小是4字节,64位系统时大小是8字节)。
结构体自引用实现方式
有2种实现方式,
方式一:
typedef struct tagNode
{
    char *pItem;
    struct tagNode *next;
} *pNode; // 注意结构体的结尾一定得有分号
方式二:
// typedef 一定要定义在struct之前
typedef struct tagNode *pNode; 
struct tageNode
{
    char *pItem;
    pNode next;
};
链表定义
定义链表和相关操作
// 定义一个用显示数据的函数指针
typedef void (*DISPLAY)(void*);
// 定义一个用于比较数据大小的函数指针
typedef int (*COMPARE)(void*, void*);
// 节点定义
typedef struct _node
{
    void *data; // 节点数据
    struct _node *next; // 下一个节点
} *pNode;
// 链表定义
typedef struct _linkedlist
{
    pNode *head;
    pNode *tail;
    pNode *current;
} LinkedList;
// 初始化链表
void init_linkedlist(LinkedList *list)
{
    list->head = NULL;
    list->tail = NULL;
    list->current = NULL;
}
// 向链表头添加数据节点
void addHead(LinkedList *list, void *data)
{
    pNode node = (pNode) malloc(sizeof(Node));
    node->data = data;
    if (list->head == NULL) {
        list->tail = node;
        node->next = NULL;
    } else {
        node->next = list->head;
    }
    list->head = node;
}
// 向链表尾部添加数据节点
void addTail(LinkedList *list, void *data)
{
    pNode node = (pNode) malloc(sizeof(Node));
    node->data = data;
    node->next = NULL;
    if (list->head == NULL) {
        list->head = node;
    } else {
        list->tail->next = node;
    }
    list->tail = node;
}
// 获取指定的节点信息
pNode getNode(LinkedList *list, COMPARE compare, void *data) 
{
    pNode node = list->head;
    while (node != NULL) {
        if (compare(node->data, data)) {
            return node;
        }
        node = node->next;
    }
    return NULL;
}
// 删除指定的节点
void deleteNode(LinkedList *list, pNode node)
{
    if (node == list->head)
    {
        if (list->head->next == NULL) {
            list->head = list->tail = NULL;
        } else {
            list->head = list->head->next;
        }
    } else {
        pNode tmp = list->head;
        while (tmp != NULL && tmp->next != node)
        {
            tmp = tmp->next;
        }
        if (tmp != NULL) {
            tmp->next = node->next;
        }
    }
    
    free(node);
}
// 展示数据
void displayList(LinkedList *list, DISPLAY display)
{
    printf("\nLinkedList shown:\n");
    pNode node = list->head;
    while (node != NULL) {
        display(node->data);
        node = node->next;
    }
}
// 比较函数
int compareInt(int *e1, int *e2)
{
    return *e1 == *e2;
}
// 显示数据
void displayIntVal(int *e)
{
    printf("%d\n", *e);
}
使用示例
1.从链表头部开始添加数据
    LinkedList linkedList;
    // 初始化
    init_linkedlist(&linkedList);
    int a = 20;
    int b = 30;
    int c = 40;
    int *ptr_1 = &a;
    int *ptr_2 = &b;
    int *ptr_3 = &c;
    addHead(&linkedList, ptr_1);
    addHead(&linkedList, ptr_2);
    addHead(&linkedList, ptr_3);
    displayList(&linkedList, (DISPLAY)displayIntVal);
打印结果:
LinkedList shown:
40
30
20
2.从链表尾部添加数据
    LinkedList linkedList;
    // 初始化
    init_linkedlist(&linkedList);
    int a = 20;
    int b = 30;
    int c = 40;
    int *ptr_1 = &a;
    int *ptr_2 = &b;
    int *ptr_3 = &c;
    addTail(&linkedList, ptr_1);
    addTail(&linkedList, ptr_2);
    addTail(&linkedList, ptr_3);
    displayList(&linkedList, (DISPLAY)displayIntVal);
打印结果:
LinkedList shown:
20
30
40
3.获取指定的节点
    LinkedList linkedList;
    // 初始化
    init_linkedlist(&linkedList);
    int a = 20;
    int b = 30;
    int c = 40;
    int *ptr_1 = &a;
    int *ptr_2 = &b;
    int *ptr_3 = &c;
    addTail(&linkedList, ptr_1);
    addTail(&linkedList, ptr_2);
    addTail(&linkedList, ptr_3);
    pNode node = getNode(&linkedList, (COMPARE) compareInt, ptr_2);
    printf("node val is %d\n", *((int *)node->data));
打印结果:
node val is 30
4.删除指定的节点
    LinkedList linkedList;
    // 初始化
    init_linkedlist(&linkedList);
    int a = 20;
    int b = 30;
    int c = 40;
    int *ptr_1 = &a;
    int *ptr_2 = &b;
    int *ptr_3 = &c;
    addTail(&linkedList, ptr_1);
    addTail(&linkedList, ptr_2);
    addTail(&linkedList, ptr_3);
    pNode node = getNode(&linkedList, (COMPARE) compareInt, ptr_2);
    printf("node val is %d\n", *((int *)node->data));
    deleteNode(&linkedList, node);
    displayList(&linkedList, (DISPLAY)displayIntVal);
打印结果:
node val is 30
LinkedList shown:
20
40
以上就是全部的内容,如有错误,欢迎留言交流或者关注公众号交流。