//Linux内核链表(企业级链表) #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<string.h> #define offscfof(TYPE,MEMBER) ((size_t)&((TYPE *)0)->MEMBER) #define container_of(ptr,type,member) (type *)((char *)ptr-offscfof(type,member)) typedef struct _node{ struct _node *pNext; }Node; typedef struct _student1{ int num; char name[20]; Node mynode; }Student1; //说明:结构体也可以写成以下模式 //typedef struct _student1{ // Node mynode; // int num; // char name[20]; //}Student1; //这样一来,就不需要计算链表节点属性在结构体中的偏移量了,简单实用 //我之所以写的复杂是为了深刻理解其原理 //创建链表 int SList_Create(Node **pout/*out*/); //获取链表长度 int Get_List_Len(Node *pin/*in*/); //查找指定位置节点 int FindNode(Node *pin/*in*/, Node **pdel/*out*/, int pos/*in*/); //插入指定位置节点 int InsertOption(Node *pin/*in*/, Node *pnode/*in*/, int pos/*in*/); //删除指定节点 int RemoveNode(Node *pin/*in*/, Node **pdel/*out*/, int pos/*in*/); void main(){ //创建链表指针 Node *phead; int i = 0,j=0; int ret = SList_Create(&phead); //说明:为什么我要创建一个无用的头节点 //理由①:不创建一个头节点,那么初始化函数SList_Create()就没有必要存在 //理由②:插入第一个节点的时候无法插入,以为没有头结点,所以插不进去第一个节点(这是主要理由) if (ret!=0) { printf("创建链表头节点失败! "); } //添加新节点 Student1 *pa = (Student1 *)malloc(sizeof(Student1)); pa->num = 1; strcpy(pa->name, "小米"); pa->mynode.pNext = NULL; ret=InsertOption(phead, &pa->mynode, Get_List_Len(phead)); if (ret != 0) { printf("添加新节点a失败! "); goto END; } Student1 *pb = (Student1 *)malloc(sizeof(Student1)); pb->num = 1; strcpy(pb->name, "小明"); pb->mynode.pNext = NULL; ret = InsertOption(phead, &pb->mynode, Get_List_Len(phead)); if (ret != 0) { printf("添加新节点b失败! "); goto END; } //打印出所有的节点 for (j = 0; j < Get_List_Len(phead); j++) { Node *temp = NULL; Student1 *temp2 = NULL; FindNode(phead, &temp, j); if (temp==NULL) { printf("查询节点失败 "); } else{ temp2 = container_of(temp, Student1, mynode); printf("学生的编号:%d;学生的姓名%s ", temp2->num, temp2->name); } } END: //删除所有链表节点 while (Get_List_Len(phead)){ Node *temp = NULL; Student1 *temp2 = NULL; RemoveNode(phead, &temp, 0); temp2 = container_of(temp, Student1, mynode); if (temp == NULL) { printf("节点删除失败! "); } else{ if (temp2 != NULL) { free(temp2); } } } //释放头节点 if (phead==NULL) { free(phead); } system("pause"); } //创建链表(顺序创建链表) int SList_Create(Node **pout/*out*/){ int ERRO_MSG = 0; if (pout==NULL) { ERRO_MSG = 1; printf("pout==NULL erro msg:%d ", ERRO_MSG); return ERRO_MSG; } Node *pM = (Node *)malloc(sizeof(Node)); pM->pNext = NULL; *pout = pM; return ERRO_MSG; } //获取链表长度 int Get_List_Len(Node *pin/*in*/){ Node *pHead = NULL, *pCurrent = NULL; int index = 0; pCurrent = pin->pNext; while (pCurrent){ pCurrent = pCurrent->pNext; index++; } return index; } //查找指定位置节点 int FindNode(Node *pin/*in*/, Node **pnode/*out*/, int pos/*in*/){ int ERRO_MSG = 0; if (pin == NULL || pnode == NULL) { ERRO_MSG = 1; printf("pin == NULL || pnode==NULL erro msg:%d ", ERRO_MSG); return ERRO_MSG; } Node *pHead = NULL, *pCurrent = NULL, *pMalloc = NULL, *pPrior = NULL; pCurrent = pPrior = pin->pNext; if (pCurrent==NULL) { ERRO_MSG = 2; printf("链表中暂时没有数据 erro msg:%d ", ERRO_MSG); return ERRO_MSG; } int index = 0; while (pCurrent){ if (index==pos) { *pnode = pCurrent; break; } pPrior = pCurrent; pCurrent = pCurrent->pNext; index++; } if (*pnode==NULL) { ERRO_MSG = 3; printf("链表中没有找到该节点 erro msg:%d ", ERRO_MSG); return ERRO_MSG; } return ERRO_MSG; } //插入指定位置节点 int InsertOption(Node *pin/*in*/, Node *pnode/*in*/, int pos/*in*/){ int ERRO_MSG = 0; if (pin == NULL || pnode==NULL) { ERRO_MSG = 1; printf("pin == NULL || pnode==NULL erro msg:%d ", ERRO_MSG); return ERRO_MSG; } Node *pHead = NULL, *pCurrent = NULL, *pMalloc = NULL,*pPrior=NULL; pHead = pPrior = pin; pCurrent = pin->pNext; pMalloc = pnode; if (pCurrent==NULL) { if (pos==0) { pHead->pNext = pMalloc; return ERRO_MSG; } else{ ERRO_MSG = 2; printf("链表为空,无法在指定位置插入节点 ", ERRO_MSG); return ERRO_MSG; } } int index = 0; while (pCurrent){ if (pos == index) { pPrior->pNext = pMalloc; pMalloc->pNext = pCurrent; return ERRO_MSG; } pPrior = pCurrent; pCurrent = pCurrent->pNext; index++; } pPrior->pNext = pMalloc; return ERRO_MSG; } //删除指定节点 int RemoveNode(Node *pin/*in*/, Node **pdel/*out*/, int pos/*in*/){ int ERRO_MSG = 0; if (pin == NULL || pdel==NULL) { ERRO_MSG = 1; printf("pin == NULL || pdel==NULL erro msg:%d ", ERRO_MSG); return ERRO_MSG; } Node *pHead = NULL, *pCurrent = NULL, *pMalloc = NULL, *pPrior = NULL; pHead = pPrior = pin; pCurrent = pin->pNext; if (pCurrent==NULL) { ERRO_MSG = 2; printf("你要删除的链表为空! erro msg:%d ", ERRO_MSG); return ERRO_MSG; } int index = 0, flag = 0; while (pCurrent){ if (index == pos) { pPrior->pNext = pCurrent->pNext; *pdel = pCurrent; break; } pPrior = pCurrent; pCurrent = pCurrent->pNext; index++; } if (*pdel==NULL) { ERRO_MSG = 3; printf("链表中没有该位置的节点! erro msg:%d ", ERRO_MSG); return ERRO_MSG; } return ERRO_MSG; }