该链表的节点结构不像初学者所接受的那种业务节点包含指针节点如同:
typedef struct TeacherNode
{
int age;
char* name;
struct TeacherNode*next
}LinkListNode
学习了内核链表的思想将业务节点和指针节点进行分离,便于底层封装和维护结构如下:
typedef struct LinklistNodeNext
{
struct LinklistNodeNext* next
}NodeNext
typedef struct TeacherNode
{
NodeNext next;
int age;
char* name
}
通过学习,自己对链表封装有了更深刻的认识,下面来学习一下内核怎么封装庞大的业务节点,实现链式存储
底层头文件:
#ifndef _MYLINKLIST_H_
#define _MYLINKLIST_H_
//Linux内核链表用的也是这种结构,指针节点与业务节点分离的原则
typedef void LinkList;
typedef struct _tag_linklistnode
{
struct _tag_linklistnode* next;
}LinkListNode;
LinkList* LinkList_Create();
void LinkList_Destroy(LinkList* linklist);
void LinkList_Clear(LinkList* linklist);
int LinkList_Length(LinkList* linklist);
int LinkList_Insert(LinkList* linklist,LinkListNode* node,int pos);
LinkListNode* LinkList_Get(LinkList* linklist,int pos);
LinkListNode* LinkList_Delete(LinkList* linklist,int pos);
#endif
头文件实现:
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "linklist.h"
//底层自己的链表结构
typedef struct _tag_MyLinkList
{
LinkListNode head;
int length;
}TLinkList;
LinkList* LinkList_Create()
{
TLinkList* tlinklist = (TLinkList*)malloc(sizeof(TLinkList));
if (tlinklist == NULL)
{
return NULL;
}
tlinklist->length = 0;
//设置头结点
tlinklist->head.next = NULL;
return tlinklist;
}
void LinkList_Destroy(LinkList* linklist)
{
TLinkList* tlinklist = (TLinkList*)linklist;
if (tlinklist == NULL)
{
return;
}
free(tlinklist);
}
void LinkList_Clear(LinkList* linklist)
{
TLinkList* tlinklist = (TLinkList*)linklist;
if (tlinklist == NULL)
{
return;
}
tlinklist->length = 0;
tlinklist->head.next = NULL;
}
int LinkList_Length(LinkList* linklist)
{
TLinkList* tlinklist = (TLinkList*)linklist;
if (tlinklist == NULL)
{
return 0;
}
return tlinklist->length;
}
int LinkList_Insert(LinkList* linklist, LinkListNode* node, int pos)
{
//元素插入
int i = 0;
TLinkList* tlinklist = (TLinkList*)linklist;
LinkListNode* current;
if (tlinklist == NULL || node == NULL || pos < 0)
{
return -1;
}
current = &tlinklist->head;
for (i = 0; i < pos && current->next != NULL; i++)
{
current = current->next;
}
node->next = current->next;
current->next = node;
//node 节点前面的指针位置
tlinklist->length++;
return 0;
}
LinkListNode* LinkList_Get(LinkList* linklist, int pos)
{
int i = 0;
LinkListNode* current;
TLinkList* tlinklist = (TLinkList*)linklist;
if (tlinklist == NULL || pos < 0)
{
return NULL;
}
current = &tlinklist->head;
for (i = 0; i < pos;i++)
{
current = current->next;
}
return current->next;
}
LinkListNode* LinkList_Delete(LinkList* linklist, int pos)
{
int i = 0;
LinkListNode* current;
LinkListNode* tmp;
TLinkList* tlinklist = (TLinkList*)linklist;
if (tlinklist == NULL || pos < 0 || pos > tlinklist->length)
{
return NULL;
}
current = &tlinklist->head;
for (i = 0; i < pos;i++)
{
current = current->next;
}
tmp = current->next;
current->next = tmp->next;
tlinklist->length--;
return tmp;
}
上层业务流程模拟:
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "linklist.h"
typedef struct _tag_teacher
{
LinkListNode node;
char* name;
int age;
}Teacher;
void TestDemo1()
{
int i = 0, ret = 0;
Teacher t1, t2, t3, t4, t5;
t1.age = 11;
t2.age = 22;
t3.age = 33;
t4.age = 44;
t5.age = 55;
t1.name = "shao11";
t2.name = "shao22";
t3.name = "shao33";
t4.name = "shao44";
t5.name = "shao55";
LinkList * linklist = LinkList_Create();
LinkList_Insert(linklist, (LinkListNode*)&t1, 0);
LinkList_Insert(linklist, (LinkListNode*)&t2, 0);
LinkList_Insert(linklist, (LinkListNode*)&t3, 0);
LinkList_Insert(linklist, (LinkListNode*)&t4, 0);
LinkList_Insert(linklist, (LinkListNode*)&t5, 0);
ret = LinkList_Length(linklist);
printf("length of linklist is : %d\n", ret);
for (i = 0;i < ret;i++)
{
Teacher* node = (Teacher*)LinkList_Get(linklist, i);
printf("node age:%d,node name:%s\n", node->age, node->name);
}
for (i = 0; i < ret;i++)
{
Teacher* node = (Teacher*)LinkList_Delete(linklist, 0);
printf("delete node age:%d,node name:%s\n", node->age, node->name);
}
LinkList_Destroy(linklist);
}
void main()
{
TestDemo1();
system("pause");
}
数据结构真的是一种内功,温故而知新,每天学一点,一点一点积累。。。。。。