鏈表實現的邏輯分析圖解
爲了實現業務結點的靈活定義,我們需要定義單獨定義鏈表結點來實現鏈表的串接與查找,而要讓業務結點包含鏈表結點,以實現通過鏈表結點將業務結點串接起來。
而爲了實現業務結點與鏈表結點的地址統一,我們在定義業務結點時要將鏈表結點包含在頭部,以實現目的。 示意圖如下圖所示。
鏈表結點定義:
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);
}