c语言——单向链表
此版链表需要手动管理内存,版本二为优化版c语言——单向链表II。
头文件LinkList.h
#pragma once
#include<stdlib.h>
#include<string.h>
#include<stdio.h>
#ifdef __cplusplus
extern "C"{
#endif
typedef void * LinkList;
typedef void(*FOREACH)(void *);
typedef int(*COMPARE)(void *,void *);
//初始化链表
LinkList Init_LinkList();
//插入节点
void Insert_LinkList(LinkList list,int pos,void *data);
//遍历链表
void Foreach_LinkList(LinkList list, FOREACH myforeach);
//按位置删除
void RemoveByPos_LinkList(LinkList list,int pos);
//按值删除
void RemoveByVal_LinkList(LinkList list, void *data, COMPARE compare);
//清空链表
void Clear_LinkList(LinkList list);
//大小
int Size_LinkList(LinkList list);
//销毁链表
void Destroy_LinkList(LinkList list);
#ifdef __cplusplus
}
#endif
单向链表LinkList.c
初始化链表
#include"LinkList.h"
//链表节点数据类型
struct LinkNode
{
void *data;
struct LinkNode *next;
};
//链表数据类型
struct LList
{
struct LinkNode header;
int size;
};
//初始化链表
LinkList Init_LinkList()
{
struct LList *list = malloc(sizeof(struct LList));
if (NULL == list)
{
return NULL;
}
list->header.data = NULL;
list->header.next = NULL;
list->size = 0;
return list;
}
插入节点
//插入节点
void Insert_LinkList(LinkList list, int pos, void *data)
{
if (NULL == list)
{
return;
}
if (NULL == data)
{
return;
}
struct LList * mylist = (struct LList *)list;
if (pos < 0 || pos > mylist->size)
{
pos = mylist->size;
}
//查找插入位置
struct LinkNode *pCurrent = &(mylist->header);
for (int i = 0; i < pos; ++i)
{
pCurrent = pCurrent->next;
}
//创建新节点
struct LinkNode *newnode = malloc(sizeof(struct LinkNode));
newnode->data = data;
newnode->next = NULL;
//新节点插入到链表中
newnode->next = pCurrent->next;
pCurrent->next = newnode;
mylist->size++;
}
遍历链表
//遍历链表
void Foreach_LinkList(LinkList list, FOREACH myforeach) /*回调函数*/
{
if (NULL == list)
{
return;
}
if (NULL == myforeach)
{
return;
}
struct LList * mylist = (struct LList *)list;
struct LinkNode *pCurrent = mylist->header.next;
while (pCurrent != NULL)
{
myforeach(pCurrent->data);
pCurrent = pCurrent->next;
}
}
按位置删除
//按位置删除
void RemoveByPos_LinkList(LinkList list, int pos)
{
if (NULL == list)
{
return;
}
struct LList *mylist = (struct LList *)list;
if (pos < 0 || pos > mylist->size - 1)
{
return;
}
//找位置
struct LinkNode *pCurrent = &(mylist->header);
for (int i = 0; i < pos; ++i)
{
pCurrent = pCurrent->next;
}
//先保存待删除结点
struct LinkNode *pDel = pCurrent->next;
//重新建立待删除结点的前驱和后继结点关系
pCurrent->next = pDel->next;
//释放删除节点内存
free(pDel);
pDel = NULL;
mylist->size--;
}
按值删除
//按值删除
void RemoveByVal_LinkList(LinkList list, void *data, COMPARE compare)
{
if (NULL == list)
{
return;
}
if (NULL == data)
{
return;
}
if (NULL == compare)
{
return;
}
struct LList *mylist = (struct LList *)list;
//辅助指针变量
struct LinkNode *pPrev = &(mylist->header);
struct LinkNode *pCurrent = pPrev->next;
while (pCurrent != NULL)
{
if (compare(pCurrent->data, data))
{
//找到了
pPrev->next = pCurrent->next;
//释放删除节点内存
free(pCurrent);
pCurrent = NULL;
mylist->size--;
break;
}
pPrev = pCurrent;
pCurrent = pCurrent->next;
}
}
清空链表
void Clear_LinkList(LinkList list)
{
if (NULL == list)
{
return;
}
struct LList *mylist = (struct LList *)list;
//辅助指针变量
struct LinkNode *pCurrent = mylist->header.next;
while (pCurrent != NULL)
{
//先缓存下一个节点的地址
struct LinkNode *pNext = pCurrent->next;
//释放当前结点内存
free(pCurrent);
pCurrent = pNext;
}
mylist->header.next = NULL;
mylist->size = 0;
}
大小
//大小
int Size_LinkList(LinkList list)
{
if (NULL == list)
{
return -1;
}
struct LList *mylist = (struct LList *)list;
return mylist->size;
}
销毁链表
//销毁链表
void Destroy_LinkList(LinkList list)
{
if (NULL == list)
{
return;
}
//清空链表
Clear_LinkList(list);
free(list);
list = NULL;
}
单向链表测试
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include"LinkList.h"
struct Person
{
char name[64];
int age;
};
void myPrint(void *data)
{
struct Person *person = (struct Person *)data;
printf("Name:%s Age:%d\n",person->name,person->age);
}
int myComapre(void *d1,void *d2)
{
struct Person *p1 = (struct Person *)d1;
struct Person *p2 = (struct Person *)d2;
#if 0
if (strcmp(p1->name,p2->name) == 0 && p1->age == p2->age)
{
return 1;
}
return 0;
#endif
return strcmp(p1->name, p2->name) == 0 && p1->age == p2->age;
}
void test()
{
//创建链表
LinkList list = Init_LinkList();
//创建数据
struct Person p1 = { "aaa", 10 };
struct Person p2 = { "bbb", 20 };
struct Person p3 = { "ccc", 30 };
struct Person p4 = { "ddd", 40 };
struct Person p5 = { "eee", 50 };
struct Person p6 = { "fff", 60 };
struct Person p7 = { "ggg", 70 };
//插入数据
Insert_LinkList(list, 0, &p1);
Insert_LinkList(list, 0, &p2);
Insert_LinkList(list, 1, &p3); //2 3 1
Insert_LinkList(list, 2, &p4); //2 3 4 1
Insert_LinkList(list, 20, &p5); //2 3 4 1 5
Insert_LinkList(list, 3, &p6); //2 3 4 6 1 5
Insert_LinkList(list, 6, &p7); //2 3 4 6 1 5 7
Foreach_LinkList(list, myPrint);
printf("----------------------\n");
printf("List Size:%d\n", Size_LinkList(list));
RemoveByPos_LinkList(list, 3);
printf("----------------------\n");
Foreach_LinkList(list, myPrint);
struct Person pDelPerson = { "ggg", 70 };
RemoveByVal_LinkList(list, &pDelPerson, myComapre);
printf("----------------------\n");
Foreach_LinkList(list, myPrint);
//清空链表
Clear_LinkList(list);
printf("----------------------\n");
printf("List Size:%d\n", Size_LinkList(list));
//销毁链表
Destroy_LinkList(list);
}
int main(){
test();
system("pause");
return EXIT_SUCCESS;
}
运行
capacity:5
capacity:10
Name:ccc Age:30
Name:eee Age:50
Name:ddd Age:40
Name:bbb Age:20
Name:aaa Age:10
Name:fff Age:60
---------------
Name:ccc Age:30
Name:eee Age:50
Name:bbb Age:20
Name:aaa Age:10
Name:fff Age:60
---------------
Name:ccc Age:30
Name:eee Age:50
Name:bbb Age:20
Name:fff Age:60