两种通用链表(Linux 内核链表)

来源:互联网 发布:围棋打谱软件下载 编辑:程序博客网 时间:2024/05/22 11:38

Linux 内核链表(通用版)

以下是头文件

#define _CRT_SECURE_NO_WARNINGS#ifndef __LINKLIST_H__#define __LINKLIST_H__#include <stdio.h>#include <stdlib.h>#include <string.h>#include <stdbool.h>typedef struct _Tag_LinkNode  //用来保存下一个节点{struct _Tag_LinkNode *next;}LinkNode;typedef void* LLink;typedef void(*TYPE_PRINT)(LinkNode *);//回调函数,打印typedef bool(*TYPE_COMPARE)(LinkNode *, LinkNode *);//回调函数,比较LLink Init_LinkList();//初始化 返回void *类型的指针void Insert_LinkNode(LLink *head,int pos,LinkNode *data); //插入(通过位置),传递的也是void *类型指针 ,在函数实现内部转换成需要的类型void PushFront_LinkNode(LLink *head, LinkNode *data);//插入头部void PushBack_LinkNode(LLink *head, LinkNode *data);//插入尾部LinkNode * RemoveByPos_LinkNode(LLink *head, int pos);//删除(通过位置)LinkNode * PopFront(LLink *head);//删除头部LinkNode * PopBack(LLink *head);//删除尾部void RemoveByVal_LinkNode(LLink *head, LinkNode * data , TYPE_COMPARE compare);//删除(通过值得比较)int GetLinkListLen(LLink *head);//获取长度void Destroy_LinkList(LLink *head);//销毁void Foreach(LLink *head, TYPE_PRINT print);//遍历打印#endif

以下是函数的实现:

#include "LinkList.h"typedef struct _Tag_LinkList //此处对用户隐藏{LinkNode header;int size;}LinkList;LLink Init_LinkList()//初始化{LinkList *list = (LinkList *)malloc(sizeof(LinkList));if (list == NULL){return NULL;}list->header.next = NULL;list->size = 0;return list;}void Insert_LinkNode(LLink *head, int pos, LinkNode *data){if (head == NULL || data == NULL){return;}LinkList *temp =(LinkList *)head;if (pos < 0 || pos > temp->size)//越界转换成尾插{pos = temp->size;}LinkNode * pCurrent = &(temp->header);for (int i = 0; i < pos; i++){pCurrent = pCurrent->next;}data->next = pCurrent->next;pCurrent->next = data;temp->size++;}void PushFront_LinkNode(LLink *head, LinkNode *data)//头插{if (head == NULL || data == NULL){return;}Insert_LinkNode(head, 0, data);}void PushBack_LinkNode(LLink *head, LinkNode *data)//尾插{if (head == NULL || data == NULL){return;}LinkList *temp = (LinkList *)head;Insert_LinkNode(head, temp->size, data);}LinkNode * RemoveByPos_LinkNode(LLink *head, int pos)//删除通过位置  {if (head == NULL){return NULL;}LinkList *temp = (LinkList *)head;if (pos < 0 || pos >= temp->size)//如果位置小于0或者 大于等于链表的长度返回{return NULL;}LinkNode *pCurrent = &(temp->header);for (int i = 0; i < pos; i++){pCurrent = pCurrent->next;}LinkNode *DelNode = pCurrent->next;//保存将要删除的节点pCurrent->next = DelNode->next;temp->size--;return DelNode;//返回要删除节点的位置}void RemoveByVal_LinkNode(LLink *head, LinkNode * data, TYPE_COMPARE compare)//通过值来删除 , 要用到一个比较的回调函数{if (head == NULL || data == NULL || compare == NULL){return;}LinkList *temp = (LinkList *)head;if (temp->size == 0)//如果链表为空 ,则直接返回{return;}LinkNode *pPrev = &(temp->header);LinkNode *pCurrent = temp->header.next;while (pCurrent){if (compare(pCurrent, data))//如果是要删除的节点{pPrev->next = pCurrent->next;temp->size--;break;}pPrev = pCurrent;pCurrent = pCurrent->next;}if (pCurrent == NULL){printf("没有找到要删除的数据\n");}}LinkNode * PopFront(LLink *head)//头删{if (head == NULL){return NULL;}return RemoveByPos_LinkNode(head, 0);}LinkNode * PopBack(LLink *head)//尾删{if (head == NULL){return NULL;}LinkList * temp = (LinkList *)head;return RemoveByPos_LinkNode(head, temp->size-1);}int GetLinkListLen(LLink *head)//获取链表长度{if (head == NULL){return 0;}LinkList *temp = (LinkList *)head;return temp->size;}void Destroy_LinkList(LLink *head)//销毁链表{if (head == NULL){return;}free(head);head = NULL;}void Foreach(LLink *head, TYPE_PRINT print)//遍历打印链表{if (head == NULL || print == NULL){return;}LinkList *temp = (LinkList *)head;LinkNode *pCurrent = temp->header.next;for (int i = 0; i < temp->size; i++){print(pCurrent);pCurrent = pCurrent->next;}}

以下是测试函数:

#include "LinkList.h"typedef struct _Tag_Teacher{LinkNode next;//保存下一个节点char name[64];int age;}Teacher;void print(LinkNode * data)//打印的函数{if (data == NULL){return;}Teacher * pT = (Teacher *)data;printf("name: %s       age:%d\n", pT->name, pT->age);}bool compare(LinkNode *p1, LinkNode *p2)//比较的回调函数{if (p1 == NULL || p2 == NULL){return false;}Teacher *pp1 = (Teacher *)p1;Teacher *pp2 = (Teacher *)p2;if ((strcmp(pp1->name, pp2->name) == 0) && (pp1->age == pp2->age)){return true;}return false;}void test(){Teacher p1, p2, p3, p4, p5, p6;strcpy(p1.name, "aaa");strcpy(p2.name, "bbb");strcpy(p3.name, "ccc");strcpy(p4.name, "ddd");strcpy(p5.name, "eee");strcpy(p6.name, "fff");p1.age = 10;p2.age = 20;p3.age = 30;p4.age = 40;p5.age = 50;p6.age = 60;LLink *list = Init_LinkList();//获取链表的头Insert_LinkNode(list, 1, (LinkNode *)&p1);PushBack_LinkNode(list, (LinkNode *)&p2);Insert_LinkNode(list, 1, (LinkNode *)&p3);//40 10 30 20 50 60 PushFront_LinkNode(list, (LinkNode *)&p4);Insert_LinkNode(list, 100, (LinkNode *)&p5);Insert_LinkNode(list, -1, (LinkNode *)&p6);Foreach(list, print);printf("\n------------------------------------------------------\n");Teacher *t = NULL;t =(Teacher *)PopFront(list);printf("name: %s       age:%d\n", t->name, t->age);printf("\n**************************************************\n");PopBack(list);Foreach(list, print);printf("\n------------------------------------------------------\n");RemoveByPos_LinkNode(list, 1);RemoveByPos_LinkNode(list, 111);RemoveByVal_LinkNode(list, (LinkNode *)&p1, compare);Foreach(list, print);printf("\n------------------------------------------------------\n");int len = GetLinkListLen(list);printf("链表现在的长度是%d\n", len);Destroy_LinkList(list);}void main(){test();system("pause");}

以下是第二种通用链表,链表中保存指针域和数据域

头文件:

#ifndef LINKLIST_H#define LINKLIST_H#include<stdlib.h>//链表节点typedef struct _LINKNODE{void* data; //数据域struct _LINKNODE* next; //指针域}LinkNode;//链表typedef struct _LINKLIST{LinkNode header; //头结点int size;//链表大小}LList;typedef void* LinkList;//比较函数指针typedef int(DATA_COMPARE)(void*, void*);//打印函数指针typedef void(DATA_PRINT)(void*);//初始化LinkList Init_LinkList();//指定位置插入void Insert_LinkList(LinkList list,int pos,void* data);//头部插入操作void PushFront_LinkList(LinkList list, void* data);//尾部插入操作void PushBack_LinkList(LinkList list, void* data);//指定位置删除void RemoveByPos_LinkList(LinkList list,int pos);//头部删除操作void PopFront_LinkList(LinkList list);//尾部删除操作void PopBack_LinkList(LinkList list);//值删除void RemoveByVal_LinkList(LinkList list, void* data, DATA_COMPARE compare);//获得指定位置元素void* Get_LinkList(LinkList list,int pos);//链表大小int Size_LinkList(LinkList list);//遍历链表void Print_LinkList(LinkList list, DATA_PRINT print);//销毁链表void Destroy_LinkList(LinkList list);#endif

函数实现:

#include"LinkList.h"//初始化LinkList Init_LinkList(){LList* list = (LList*)malloc(sizeof(LList));list->size = 0;list->header.next = NULL;return list;}//指定位置插入void Insert_LinkList(LinkList list, int pos, void* data){if (list == NULL){return;}if (data == NULL){return;}LList* mlist = (LList*)list;//判断位置是否越界 位置从0开始,如果越界,默认插入到尾部if (pos < 0 || pos > mlist->size){pos = mlist->size;}//查找插入位置LinkNode* pCurrent = &(mlist->header);int i = 0;for (; i < pos;i++){pCurrent = pCurrent->next;}//创建新节点LinkNode* newnode = (LinkNode*)malloc(sizeof(LinkNode));newnode->data = data;newnode->next = NULL;//新节点入链表newnode->next = pCurrent->next;pCurrent->next = newnode;mlist->size++;}//头部插入操作void PushFront_LinkList(LinkList list, void* data){if (list == NULL){return;}if (data == NULL){return;}Insert_LinkList(list,0,data);}//尾部插入操作void PushBack_LinkList(LinkList list, void* data){if (list == NULL){return;}if (data == NULL){return;}LList* mlist = (LList*)list;Insert_LinkList(list, mlist->size, data);}//指定位置删除void RemoveByPos_LinkList(LinkList list, int pos){if (list == NULL){return;}LList* mlist = (LList*)list;if (pos < 0 || pos >= mlist->size){return;}//判断链表是否为空if (mlist->size == 0){return;}//查找删除节点的前一个节点LinkNode* pCurrent = &(mlist->header);int i = 0;for (; i < pos;i++){pCurrent = pCurrent->next;}//缓存待删除节点LinkNode* pDel = pCurrent->next;//重新连接被删除节点前驱和后继节点pCurrent->next = pDel->next;//释放被删除节点内存free(pDel);mlist->size--;}//头部删除操作void PopFront_LinkList(LinkList list){if (list == NULL){return;}LList* mlist = (LList*)list;if (mlist->size == 0){return;}RemoveByPos_LinkList(list, 0);}//尾部删除操作void PopBack_LinkList(LinkList list){if (list == NULL){return;}LList* mlist = (LList*)list;if (mlist->size == 0){return;}RemoveByPos_LinkList(list, mlist->size - 1);}//值删除void RemoveByVal_LinkList(LinkList list, void* data, DATA_COMPARE compare){if (list == NULL){return;}if (data == NULL){return;}if (compare == NULL){return;}LList* mlist = (LList*)list;if (mlist->size == 0){return;}//查找删除节点LinkNode* pPrev = &(mlist->header);LinkNode* pCurrent = pPrev->next;while (pCurrent != NULL){if (compare(pCurrent->data,data)){pPrev->next = pCurrent->next;//释放删除节点内存free(pCurrent);mlist->size--;break;}pPrev = pCurrent;pCurrent = pCurrent->next;}}//获得指定位置元素void* Get_LinkList(LinkList list, int pos){if (list == NULL){return NULL;}LList* mlist = (LList*)list;if (pos < 0 || pos > mlist->size){return NULL;}//查找pos前一个位置的节点LinkNode* pCurrent = &(mlist->header);for (int i = 0; i < pos;i++){pCurrent = pCurrent->next;}return pCurrent->next->data;}//链表大小int Size_LinkList(LinkList list){if (list == NULL){return -1;}LList* mlist = (LList*)list;return mlist->size;}//遍历链表void Print_LinkList(LinkList list, DATA_PRINT print){if (list == NULL){return;}LList* mlist = (LList*)list;//赋值指针LinkNode* pCurrent = mlist->header.next;while (pCurrent!=NULL){print(pCurrent->data);pCurrent = pCurrent->next;}}//销毁链表void Destroy_LinkList(LinkList list){if (list == NULL){return;}LList* mlist = (LList*)list;LinkNode* pCurrent = mlist->header.next;while (pCurrent != NULL){//缓存待删除节点下一个节点LinkNode* pNext = pCurrent->next;free(pCurrent);pCurrent = pNext;}//最后释放链表内存free(mlist);printf("链表内存释放!\n");}

测试函数:

#define _CRT_SECURE_NO_WARNINGS#include<stdio.h>#include<stdlib.h>#include<string.h>#include"LinkList.h"typedef struct _PERSON{char name[64];int age;}Person;void MyPrint(void* data){Person* p = (Person*)data;printf("Name:%s Age:%d\n",p->name,p->age);}int MyCompare(void* data1,void* data2){Person* p1 = (Person*)data1;Person* p2 = (Person*)data2;return strcmp(p1->name, p2->name) == 0 && p1->age == p2->age;}int main(){//初始化链表LinkList list = Init_LinkList();//创建数据Person p1 = { "aaa", 12 };Person p2 = { "bbb", 13 };Person p3 = { "ccc", 14 };Person p4 = { "ddd", 15 };Person p5 = { "eee", 16 };Person p6 = { "fff", 17 };//头插PushFront_LinkList(list, (void*)&p1);PushFront_LinkList(list, (void*)&p2);//尾插PushBack_LinkList(list, (void*)&p3);PushBack_LinkList(list, (void*)&p4);//指定位置插入Insert_LinkList(list, 2, (void*)&p5);//Insert_LinkList(list, 1, (void*)&p6);//打印Print_LinkList(list, MyPrint);//头删PopFront_LinkList(list);printf("头删结果:\n");Print_LinkList(list, MyPrint);printf("---------------------\n");//尾删PopBack_LinkList(list);printf("尾删结果:\n");Print_LinkList(list, MyPrint);printf("---------------------\n");//指定位置删除RemoveByPos_LinkList(list,1);printf("指定位置1删结果:\n");Print_LinkList(list, MyPrint);printf("---------------------\n");printf("链表长度:%d\n",Size_LinkList(list));//根据值删除RemoveByVal_LinkList(list, (void*)&p1, MyCompare);printf("根据值删结果:\n");Print_LinkList(list, MyPrint);printf("---------------------\n");//销毁链表Destroy_LinkList(list);system("pause");return EXIT_SUCCESS;}




0 0
原创粉丝点击