链表实现的逻辑分析图解
为了实现业务结点的灵活定义,我们需要定义单独定义链表结点来实现链表的串接与查找,而要让业务结点包含链表结点,以实现通过链表结点将业务结点串接起来。
而为了实现业务结点与链表结点的地址统一,我们在定义业务结点时要将链表结点包含在头部,以实现目的。 示意图如下图所示。
链表结点定义:
typedef struct _tag_LinkListNode
{
struct _tag_linkListNode* next;
}LinkListNode;
定义业务结点时将链表结点包含进来
typedef struct Teacher
{
LinkListNode node;
int age;
char name[64];
}Teacher;
linklist.h
#ifndef _MYLINKLIST_H_
#define _MYLINKLIST_H_
typedef void LinkList;
typedef struct _tag_LinkListNode
{
struct _tag_linkListNode* next;
}LinkListNode;
LinkList* LinkList_Create();
void LinkList_Destroy(LinkList* list);
void LinkList_Clear(LinkList* list);
int LinkList_Length(LinkList *list);
int LinkList_Insert(LinkList* list, LinkListNode* node, int pos);
LinkListNode* LinkList_Get(LinkList* list, int pos);
LinkListNode* LinkList_Delete(LinkList* list, int pos);
#endif // !_MYLINKLIST_H_
linklist.c
先定义一个链表句柄,注入一个头结点和存放链表长度的变量。
typedef struct _tag_LinkList
{
LinkListNode header;
int length;
}TLinkList;
创建链表,通过句柄申请链表内存,进行长度和指针初始化。将句柄的指针地址返回
LinkList* LinkList_Create()
{
TLinkList *ret = NULL;
ret = (TLinkList *)malloc(sizeof(TLinkList));
memset(ret, 0, sizeof(TLinkList));
ret->length = 0; //
ret->header.next = NULL;//
return ret;
}
销毁和清空链表
void LinkList_Destroy(LinkList* list)
{
if (list != NULL)
{
free(list);
list = NULL;
}
return ;
}
void LinkList_Clear(LinkList* list)
{
TLinkList *tList = NULL;
if (list == NULL)
{
return;
}
tList = (TLinkList *)list;
tList->length = 0;
tList->header.next = NULL;
return ;
}
返回长度
int LinkList_Length(LinkList *list)
{
TLinkList *tList = NULL;
if (list == NULL)
{
return -1;
}
tList = (TLinkList *)list;
return tList->length;
}
插入结点,定义一个current结点从头结点开始查起,到pos位置结束
int LinkList_Insert(LinkList* list, LinkListNode* node, int pos)
{
int ret = 0,i=0;
LinkListNode *current = NULL;
TLinkList *tList = NULL;
if (list == NULL || node == NULL || pos < 0)
{
ret = 0;
printf("func LinkList_Insert() err:%d \n", ret);
return ret;
}
tList = (TLinkList *)list;
current = &(tList->header);
for (i = 0; i < pos&&(current->next!=NULL); i++)
{
current = current->next;
}
node->next = current->next;
current->next = node;
tList->length++;
return 0;
}
删除结点
LinkListNode* LinkList_Delete(LinkList* list, int pos)
{
int i = 0;
LinkListNode *current = NULL;
LinkListNode *ret = NULL;
TLinkList *tList = NULL;
if (list == NULL || pos < 0)
{
printf("func LinkList_Get() err: \n");
return NULL;
}
tList = (TLinkList *)list;
current = &(tList->header);
for (i = 0; i < pos && (current->next != NULL); i++)
{
current = current->next;
}
ret = current->next;
current->next = ret->next;
tList->length--;
return ret;
}
获取结点
LinkListNode* LinkList_Get(LinkList* list, int pos)
{
int ret = 0, i = 0;
LinkListNode *current = NULL;
TLinkList *tList = NULL;
if (list == NULL || pos < 0)
{
ret = -1;
printf("func LinkList_Get() err:%d \n", ret);
return NULL;
}
tList = (TLinkList *)list;
current = &(tList->header);
for (i = 0; i < pos && (current->next != NULL); i++)
{
current = current->next;
}
return current->next;
}
测试用例
ret = LinkList_Insert(list, (LinkListNode*)&t5, 0);
for (i = 0; i < LinkList_Length(list); i++)
{
Teacher *tmp = (Teacher *)LinkList_Get(list, i);
if (tmp == NULL)
{
return;
}
printf("tmp->age:%d", tmp->age);
}