数据结构 传统链表实现
Posted 天码丶行满
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构 传统链表实现相关的知识,希望对你有一定的参考价值。
头文件:
#pragma once #include<stdlib.h> //链表结点 struct LinkNode{ void *data; struct LinkNode *next; }; //链表 struct _Linklist{ struct LinkNode header; int size; //链表结点的数目 }; typedef void *LinkList; #ifdef __cplusplus extern "C" { #endif //初始化链表 LinkList Init_LinkList(); //指定位置插入 int InsertByPos_LinkList(LinkList list, int pos, void *data); //头插 int PushFront_LinkList(LinkList list, void *data); //尾插 int PushBack_LinkList(LinkList list, void *data); //在指定值的前面插入 int InsertByVal_LinkList(LinkList list, void *oldval, void *newval, int(*isequal)(void*,void*)); //指定位置删除 int RemoveByPos_LinkList(LinkList list, int pos); //根据值删除 int RemoveByVal_LinkList(LinkList list, void *data, int(*compare)(void *, void *)); //头删 void PopFront_LinkList(LinkList list); //尾删 void PopBack_LinkList(LinkList list); //遍历 void Foreach_LinkList(LinkList list, void(*foreach)(void *)); //销毁 void Destroy_LinkList(LinkList list); #ifdef __cplusplus } #endif
头文件实现:
#include"LinkList.h" //初始化链表 LinkList Init_LinkList(){ struct _Linklist *list = malloc(sizeof(struct _Linklist)); if (NULL == list){ return NULL; } list->header.data = NULL; list->header.next = NULL; list->size = 0; return list; } //指定位置插入 0代表插入到第一个位置 int InsertByPos_LinkList(LinkList list, int pos, void *data){ if (NULL == list){ return -1; } if (NULL == data){ return -2; } struct _Linklist *llist = (struct _Linklist *)list; if (pos < 0 || pos > llist->size){ pos = llist->size; } //辅助指针变量 struct LinkNode *pCurrent = &(llist->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; //size llist->size++; return 0; } //头插 int PushFront_LinkList(LinkList list, void *data){ return InsertByPos_LinkList(list, 0, data); } //尾插 int PushBack_LinkList(LinkList list, void *data){ if (NULL == list){ return -1; } struct _Linklist *llist = (struct _Linklist *)list; return InsertByPos_LinkList(list,llist->size - 1,data); } //在指定值的前面插入 int InsertByVal_LinkList(LinkList list, void *oldval, void *newval, int(*isequal)(void*, void*)){ if(NULL ==list){ return -1; } if (NULL == oldval){ return -2; } if (NULL == newval){ return -3; } if (NULL == isequal){ return -4; } struct _Linklist *llist = (struct _Linklist *)list; //辅助指针变量 struct LinkNode *pPrev = &(llist->header); struct LinkNode *pCurrent = pPrev->next; while (pCurrent != NULL){ if (isequal(pCurrent->data, oldval)){ //创建新结点 struct LinkNode *newnode = malloc(sizeof(struct LinkNode)); newnode->data = newval; newnode->next = NULL; //新结点入链表 pPrev->next = newnode; newnode->next = pCurrent; llist->size++; break; } pPrev = pCurrent; pCurrent = pCurrent->next; } return 0; } //指定位置删除 int RemoveByPos_LinkList(LinkList list, int pos){ if (NULL == list){ return -1; } struct _Linklist *llist = (struct _Linklist *)list; if (llist->size == 0){ return 0; } if (pos < 0 || pos > llist->size - 1){ return 0; } //辅助指针变量 //找到待删除结点的前一个结点 struct LinkNode *pCurrent = &(llist->header); for (int i = 0; i < pos;i ++){ pCurrent = pCurrent->next; } //缓存下待删除结点 struct LinkNode *pDel = pCurrent->next; //重新建立待删除结点的前驱后继结点关系 pCurrent->next = pDel->next; //删除结点内存 free(pDel); pDel = NULL; llist->size--; return 0; } //根据值删除 int RemoveByVal_LinkList(LinkList list, void *data, int(*compare)(void *, void *)){ if (NULL == list){ return -1; } if (NULL == data){ return -2; } if (NULL == compare){ return -3; } struct _Linklist *llist = (struct _Linklist *)list; //辅助指针变量 struct LinkNode *pPrev = &(llist->header); struct LinkNode *pCurrent = pPrev->next; while (pCurrent != NULL){ if (compare(pCurrent->data, data)){ pPrev->next = pCurrent->next; free(pCurrent); llist->size--; break; } pPrev = pCurrent; pCurrent = pPrev->next; } return 0; } //头删 void PopFront_LinkList(LinkList list){ RemoveByPos_LinkList(list, 0); } //尾删 void PopBack_LinkList(LinkList list){ if (NULL == list){ return; } struct _Linklist *llist = (struct _Linklist *)list; RemoveByPos_LinkList(list, llist->size - 1); } //遍历 void Foreach_LinkList(LinkList list, void(*foreach)(void *)){ if (NULL == list){ return; } if (NULL == foreach){ return; } struct _Linklist *llist = (struct _Linklist *)list; //辅助指针变量 struct LinkNode *pCurrent = llist->header.next; while (pCurrent != NULL){ foreach(pCurrent->data); pCurrent = pCurrent->next; } } //销毁 void Destroy_LinkList(LinkList list){ if (NULL == list){ return; } struct _Linklist *llist = (struct _Linklist *)list; //辅助指针变量 struct LinkNode *pCurrent = llist->header.next; while (pCurrent != NULL){ //缓存下一个结点 struct LinkNode *pNext = pCurrent->next; //释放当前结点内存 free(pCurrent); //指针移动到下一个结点的位置 pCurrent = pNext; } free(llist); llist = 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 MyCompare(void *d1,void *d2){ struct Person *p1 = (struct Person *)d1; struct Person *p2 = (struct Person *)d2; return strcmp(p1->name, p2->name) == 0 && p1->age == p2->age; } void test(){ //创建测试数据 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 }; //初始化链表 LinkList list = Init_LinkList(); //将数据插入链表 InsertByPos_LinkList(list, 0, &p1); InsertByPos_LinkList(list, 0, &p2); InsertByPos_LinkList(list, 0, &p3); InsertByPos_LinkList(list, 1, &p4); InsertByPos_LinkList(list, 0, &p5); InsertByPos_LinkList(list, 0, &p6); //遍历 6 5 3 4 2 1 Foreach_LinkList(list, MyPrint); printf("-------------------\n"); printf("在name为ccc,age为30的数据前面插入:\n"); InsertByVal_LinkList(list, &p3, &p7, MyCompare); Foreach_LinkList(list, MyPrint); printf("删除位置4的数据:\n"); RemoveByPos_LinkList(list,4); Foreach_LinkList(list, MyPrint); printf("删除name为ggg age为70的数据:\n"); RemoveByVal_LinkList(list, &p7, MyCompare); Foreach_LinkList(list, MyPrint); //销毁链表 Destroy_LinkList(list); } int main(){ test(); system("pause"); return EXIT_SUCCESS; }
以上是关于数据结构 传统链表实现的主要内容,如果未能解决你的问题,请参考以下文章
C提高 7 单向链表,传统链表,通用链表,linus天才哲学代码
NC41 最长无重复子数组/NC133链表的奇偶重排/NC116把数字翻译成字符串/NC135 股票交易的最大收益/NC126换钱的最少货币数/NC45实现二叉树先序,中序和后序遍历(递归)(代码片段
817. Linked List Components - LeetCode