//线性链表头文件 #ifndef _vzhanglinklist #define _vzhanglinklist typedef struct _LinkNode{ struct _LinkNode *pnext; }LinkNode; typedef void LinkList; //创建线性链表 _declspec(dllexport) LinkList* LinkList_Create(); //销毁线性链表 _declspec(dllexport) int LinkList_Destroy(LinkList** list); //清空线性链表 _declspec(dllexport) int LinkList_Clear(LinkList* list); //获取线性链表长度 _declspec(dllexport) int LinkList_Length(LinkList* list); //线性链表指定位置插入元素 _declspec(dllexport) int LinkList_Insert(LinkList* list, LinkNode* node, int pos); //获取线性链表指定位置的元素 _declspec(dllexport) LinkNode* LinkList_Get(LinkList* list, int pos); //删除线性链表指定位置的元素 _declspec(dllexport) LinkNode* LinkList_Delete(LinkList* list, int pos); #endif;
//线性链表代码实现 #include<stdio.h> #include<stdlib.h> #include<string.h> #include"LinkList.h" /* 强调:①链表中不提供对元素的删除功能,因为链表无法知道元素的大小 ②MyLinkList结构体应该定义在方法实现的文件中,不要定义在.h文件里 因为用户不需要知道MyLinkList结构体是怎么实现的 */ //定义链表对象 typedef struct _MyLinkList{ //定义链表头结点 LinkNode head; //定义链表元素个数 int length; }MyLinkList; //创建线性链表 _declspec(dllexport) LinkList* LinkList_Create(){ //创建链表结构 MyLinkList *mylist = (MyLinkList *)malloc(sizeof(MyLinkList)); if (mylist==NULL) { printf("创建链表分配内存失败! "); return NULL; } mylist->head.pnext= NULL; mylist->length = 0; return (LinkList*)mylist; } //销毁线性链表 _declspec(dllexport) int LinkList_Destroy(LinkList** list){ int ERRO_MSG = 0; if (list == NULL) { ERRO_MSG = -1; printf("list==NULL 传入参数不可以为空! erro msg:%d ", ERRO_MSG); return ERRO_MSG; } MyLinkList * mylist = (MyLinkList *)*list; if (mylist!=NULL) { //链表的数据必须由用户删除 free(mylist); mylist = NULL; *list = NULL; } return ERRO_MSG; } //清空线性链表 _declspec(dllexport) int LinkList_Clear(LinkList* list){ int ERRO_MSG = 0; if (list == NULL) { ERRO_MSG = -1; printf("list==NULL 传入参数不可以为空! erro msg:%d ", ERRO_MSG); return ERRO_MSG; } MyLinkList * mylist = (MyLinkList *)list; mylist->head.pnext = NULL; mylist->length = 0; return ERRO_MSG; } //获取线性链表长度 _declspec(dllexport) int LinkList_Length(LinkList* list){ int ERRO_MSG = 0; if (list == NULL) { ERRO_MSG = -1; printf("list==NULL 传入参数不可以为空! erro msg:%d ", ERRO_MSG); return ERRO_MSG; } MyLinkList * mylist = (MyLinkList *)list; return mylist->length; } //线性链表指定位置插入元素 _declspec(dllexport) int LinkList_Insert(LinkList* list, LinkNode* node, int pos){ int ERRO_MSG = 0,i=0; if (list == NULL) { ERRO_MSG = -1; printf("list==NULL 传入参数不可以为空! erro msg:%d ", ERRO_MSG); return ERRO_MSG; } MyLinkList * mylist = (MyLinkList *)list; //此时current指针指向头结点 不指向第0个元素 LinkNode * current = &mylist->head; for (i = 0; i < pos&&(current->pnext!=NULL); i++) { /* current->pnext!=NULL这个判断不能缺少 这是为了链表元素的连续 也是为了current->pnext指针操作不报错 */ current = current->pnext; } /* 当在第0个位置插入 正好current此时是头结点 所以没问题 */ node->pnext = current->pnext; current->pnext = node; //元素个数+1 mylist->length++; return ERRO_MSG; } //获取线性链表指定位置的元素 _declspec(dllexport) LinkNode* LinkList_Get(LinkList* list, int pos){ int ERRO_MSG = 0, i = 0; if (list == NULL) { ERRO_MSG = -1; printf("list==NULL 传入参数不可以为空! erro msg:%d ", ERRO_MSG); return NULL; } MyLinkList * mylist = (MyLinkList *)list; //判断获取元素的位置 if (pos<0 || pos>mylist->length) { ERRO_MSG = -2; printf("该位置上没有元素! erro msg:%d ", ERRO_MSG); return NULL; } // /* 注意:此时跟插入方法有区别 插入方法中,current指向的是头结点,在本方法中current指向的是第0个元素 这是为了 获取第0个位置的元素 方便 */ LinkNode * current = mylist->head.pnext; for (i = 0; i < pos; i++) { current = current->pnext; } return current; } //删除线性链表指定位置的元素 _declspec(dllexport) LinkNode* LinkList_Delete(LinkList* list, int pos){ int ERRO_MSG = 0, i = 0; if (list == NULL) { ERRO_MSG = -1; printf("list==NULL 传入参数不可以为空! erro msg:%d ", ERRO_MSG); return NULL; } MyLinkList * mylist = (MyLinkList *)list; //判断获取元素的位置 if (pos<0 || pos>mylist->length) { ERRO_MSG = -2; printf("该位置上没有元素! erro msg:%d ", ERRO_MSG); return NULL; } //这里跟获取元素位置离又不相同 这里current指向的是头结点 LinkNode * current = &mylist->head; LinkNode * ret = NULL; for (i = 0; i < pos; i++) { current = current->pnext; } ret = current->pnext; current->pnext = ret->pnext; ret->pnext = NULL; //元素个数-1 mylist->length--; return ret; }
//线性链表测试代码 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<string.h> #include"LinkList.h" typedef struct _Student{ //必须加一个LinkNode节点 LinkNode node; char name[30]; int age; }Student; void Test(){ Student s1, s2, s3, s4, s5; int numx = 0, i = 0, ret = 0; strcpy(s1.name, "小米"); s1.age = 11; strcpy(s2.name, "小刚"); s2.age = 12; strcpy(s3.name, "小红"); s3.age = 10; strcpy(s4.name, "啸天"); s4.age = 13; strcpy(s5.name, "莲华"); s5.age = 12; //线性表指针 LinkList *list = NULL; //创建线性链表 list = LinkList_Create(); //插入元素 LinkList_Insert(list, (LinkNode *)&s1, 0); LinkList_Insert(list, (LinkNode *)&s2, 0); LinkList_Insert(list, (LinkNode *)&s3, 0); LinkList_Insert(list, (LinkNode *)&s4, 0); LinkList_Insert(list, (LinkNode *)&s5, 0); //获取元素个数 numx = LinkList_Length(list); //打印所有元素 for (i = 0; i < numx; i++) { Student *temp = (Student *)LinkList_Get(list, i); printf("我的名字是%s;我的年龄是%d ", temp->name, temp->age); } //删除线性表中的数据 Student *delem = (Student *)LinkList_Delete(list, 2); printf("我被删除了,我的名字是%s;我的年龄是%d ", delem->name, delem->age); //销毁线性表 ret = LinkList_Destroy(&list); if (ret == 0)printf("线性链表销毁成功! "); } void main(){ Test(); system("pause"); }