C语言实现带头结点的单链表(可以储存任意数据类型)
程序员文章站
2024-03-18 08:46:04
...
C语言实现带头结点的单链表,可以储存任意数据类型,用户可以自定义储存的数据类型,但数据储存的堆空间需要用户自己创建。其中回调函数可以根据用户自己的要求去查找数据结点。
list.h
#ifndef _LIST_H_
#define _LIST_H_
typedef int (*keyCmp)(void* pData, char* key);//返回 0 相等 其它 不相等
typedef struct list_s
{
void* pData;
struct list_s* next;
}List, * pList;
int createList(pList* pHead);//创建链表
int add(pList* pHead, void* pData);//添加结点(尾插)
void outList(pList pHead);//遍历链表
void* findNode(pList pHead, keyCmp cmpFun, char* key);//查找指定结点
int delNote(pList pHead, keyCmp cmpFun, char* key);//删除结点
void freeList(pList* pHead);//删除链表
#endif
list.c
#include <stdio.h>
#include "list.h"
int createList(pList* pHead)//创建链表
{
pList p = (pList)malloc(sizeof(List));
if (p == NULL)
{
return -1;
}
p->next = NULL;
*pHead = p;
return 0;
}
int add(pList * pHead, void* pData)//添加结点(尾插)
{
pList* p = pHead;
pList pNew = (pList)malloc(sizeof(List));
if (pNew == NULL)
{
return -1;
}
pNew->pData = pData;
pNew->next = NULL;
while (*p != NULL)
{
p = &((*p)->next);
}
*p = pNew;
return 0;
}
void outList(pList pHead)//遍历链表
{
printf("链表数据:\n");
while (pHead != NULL)
{
pHead = pHead-> next;
if (pHead != NULL)
{
printf("%s\n",(char *)pHead->pData);
}
}
}
void* findNode(pList pHead, keyCmp cmpFun, char* key)//查找指定结点
{
pList p = pHead->next;
while (p != NULL)
{
if (cmpFun(p->pData, key) == 0)
{
break;
}
p = p->next;
}
return p;
}
int delNote(pList pHead, keyCmp cmpFun, char* key)//删除结点
{
pList p = pHead->next;
pList q = pHead;
while (p != NULL)
{
if (cmpFun(p->pData, key) == 0)
{
q->next = p->next;
free(p->pData);//删除用户堆空间数据
free(p);//删除结点空间
return 0;
}
q = p;
p = p->next;
}
return -1;
}
void freeList(pList* pHead)//删除链表
{
pList p = (*pHead)->next;//跳过头结点
pList pTemp = NULL;
while (p != NULL)
{
pTemp = p->next;
free(p->pData);//删除用户堆空间数据
free(p);//删除结点空间
p = pTemp;
}
//删除头结点
free(*pHead);//删除头结点空间(头结点没存储用户数据)
*pHead = NULL;
}
main.c 测试文件
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "list.h"
int keyFun(void* pData, char* key)
{
if (strcmp((char*)pData, (char*)key) == 0)
{
return 0;
}
else
{
return -1;
}
}
int main()
{
pList root, p;
char* ch;
int ret;
createList(&root);
ch = (char*)malloc(sizeof(char) * 2);
strcpy(ch, "a");
add(&root, ch);
ch = (char*)malloc(sizeof(char) * 2);
strcpy(ch, "b");
add(&root, ch);
ch = (char*)malloc(sizeof(char) * 2);
strcpy(ch, "c");
add(&root, ch);
outList(root);
p = findNode(root, keyFun, "b");//查找指定结点
if (p != NULL)
{
printf("查找到的数据: %s\n", (char*)p->pData);
}
ret = delNote(root, keyFun, "c");
if (!ret)
{
printf("删除 c 成功!\n");
}
outList(root);
freeList(&root);//删除链表
outList(root);
return 0;
}