//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[];
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 = ,j=;
int ret = SList_Create(&phead);
//说明:为什么我要创建一个无用的头节点
//理由①:不创建一个头节点,那么初始化函数SList_Create()就没有必要存在
//理由②:插入第一个节点的时候无法插入,以为没有头结点,所以插不进去第一个节点(这是主要理由)
if (ret!=)
{
printf("创建链表头节点失败!\n");
}
//添加新节点
Student1 *pa = (Student1 *)malloc(sizeof(Student1));
pa->num = ;
strcpy(pa->name, "小米");
pa->mynode.pNext = NULL;
ret=InsertOption(phead, &pa->mynode, Get_List_Len(phead));
if (ret != )
{
printf("添加新节点a失败!\n");
goto END;
}
Student1 *pb = (Student1 *)malloc(sizeof(Student1));
pb->num = ;
strcpy(pb->name, "小明");
pb->mynode.pNext = NULL;
ret = InsertOption(phead, &pb->mynode, Get_List_Len(phead));
if (ret != )
{
printf("添加新节点b失败!\n");
goto END;
}
//打印出所有的节点
for (j = ; j < Get_List_Len(phead); j++)
{
Node *temp = NULL;
Student1 *temp2 = NULL;
FindNode(phead, &temp, j);
if (temp==NULL)
{
printf("查询节点失败\n");
}
else{
temp2 = container_of(temp, Student1, mynode);
printf("学生的编号:%d;学生的姓名%s\n", temp2->num, temp2->name);
}
}
END:
//删除所有链表节点
while (Get_List_Len(phead)){
Node *temp = NULL;
Student1 *temp2 = NULL;
RemoveNode(phead, &temp, );
temp2 = container_of(temp, Student1, mynode);
if (temp == NULL)
{
printf("节点删除失败!\n");
}
else{
if (temp2 != NULL)
{
free(temp2);
}
}
}
//释放头节点
if (phead==NULL)
{
free(phead);
}
system("pause");
}
//创建链表(顺序创建链表)
int SList_Create(Node **pout/*out*/){
int ERRO_MSG = ;
if (pout==NULL)
{
ERRO_MSG = ;
printf("pout==NULL erro msg:%d\n", 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 = ;
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 = ;
if (pin == NULL || pnode == NULL)
{
ERRO_MSG = ;
printf("pin == NULL || pnode==NULL erro msg:%d\n", ERRO_MSG);
return ERRO_MSG;
}
Node *pHead = NULL, *pCurrent = NULL, *pMalloc = NULL, *pPrior = NULL;
pCurrent = pPrior = pin->pNext;
if (pCurrent==NULL)
{
ERRO_MSG = ;
printf("链表中暂时没有数据 erro msg:%d\n", ERRO_MSG);
return ERRO_MSG;
}
int index = ;
while (pCurrent){
if (index==pos)
{
*pnode = pCurrent;
break;
}
pPrior = pCurrent;
pCurrent = pCurrent->pNext;
index++;
}
if (*pnode==NULL)
{
ERRO_MSG = ;
printf("链表中没有找到该节点 erro msg:%d\n", ERRO_MSG);
return ERRO_MSG;
}
return ERRO_MSG;
}
//插入指定位置节点
int InsertOption(Node *pin/*in*/, Node *pnode/*in*/, int pos/*in*/){
int ERRO_MSG = ;
if (pin == NULL || pnode==NULL)
{
ERRO_MSG = ;
printf("pin == NULL || pnode==NULL erro msg:%d\n", 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==)
{
pHead->pNext = pMalloc;
return ERRO_MSG;
}
else{
ERRO_MSG = ;
printf("链表为空,无法在指定位置插入节点\n", ERRO_MSG);
return ERRO_MSG;
}
}
int index = ;
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 = ;
if (pin == NULL || pdel==NULL)
{
ERRO_MSG = ;
printf("pin == NULL || pdel==NULL erro msg:%d\n", 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 = ;
printf("你要删除的链表为空! erro msg:%d\n", ERRO_MSG);
return ERRO_MSG;
}
int index = , flag = ;
while (pCurrent){
if (index == pos)
{
pPrior->pNext = pCurrent->pNext;
*pdel = pCurrent;
break;
}
pPrior = pCurrent;
pCurrent = pCurrent->pNext;
index++;
}
if (*pdel==NULL)
{
ERRO_MSG = ;
printf("链表中没有该位置的节点! erro msg:%d\n", ERRO_MSG);
return ERRO_MSG;
}
return ERRO_MSG;
}