C语言链表的重要性,c语言链表升级

之前的链表就是一个普通的带头的单向链表,我们不自觉的会发现这样的链表有缺陷,有关链表的删除新增查找跟链表的结构体内容耦合性太强

什么意思呢?

比如我们之前的链表的结构体

typedef struct_Teacher

{intage;struct _Teacher *next;

}Teacher;

我们有关链表所有的操作都跟这个结构体紧密的相连,如果此刻我们有另一个结构体,里面的字段都跟这个不一样,那么,我们可能还需要对这个新的结构体写一套链表操作?

相当于下面的图,呵呵,有点丑

41f0e39e64f82023b238748dbdabf69e.png

那么我们的解决方案是什么呢?,我们能不能关于不同结构体的所有操作都有一套公共方法呢?

当然是可以的!

在这之前我们必须有一个概念,结构体中的第一个元素的地址就是代表结构体的地址。

我们设计一个单纯代表数据结构的结构体,这个结构体只有下个对象的地址的指针成员

2b81db1ea5e274e09e9c9a6e84c2f2f2.png

typedef struct_tag_LinkListNode

{void *next;

}LinkListNode;

比如此刻我们有一个教师结构体,那么我们只需要在结构体的第一个成员是上面的LinkListNode对象。

形成下面的数据结构:

4ee50e0083c7949745d8a175160fa8e7.png

typedef struct_Teacher

{

LinkListNode listNode;intage;char name[50];

}Teacher;

那么,此刻我们只要在我们的对链表的操作将传过来的Teacher * 指针强转为LinkListNode *类型,查询出来的LinkListNode * 指针变量再强转为Teacher * 对象,从而对LinkListNode形成一套插入删除查询的api就可以了

以下是实现的代码:

接口:

#ifndef _MYLINKLIST_H_#define _MYLINKLIST_H_typedefvoidLinkList;

typedefstruct_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, intpos);

LinkListNode* LinkList_Get(LinkList* list, intpos);

LinkListNode* LinkList_Delete(LinkList* list, intpos);#endif

实现:

#include "stdio.h"#include"stdlib.h"#include"linklist.h"typedefstruct_tag_LinkList

{//头节点

LinkListNode header;intlength;

}TLinkList;/************************************************************************/

/*创建list并初始化一个头节点*/

/************************************************************************/LinkList*LinkList_Create()

{

TLinkList*tlist = (TLinkList *)malloc(sizeof(TLinkList));if (tlist ==NULL)

{returnNULL;

}

tlist->length = 0;

tlist->header.next =NULL;returntlist;

}void LinkList_Destroy(LinkList*list)

{if (list ==NULL)

{return;

}free(list);

}/************************************************************************/

/*清空list链表*/

/************************************************************************/

void LinkList_Clear(LinkList*list)

{if (list ==NULL)

{return;

}

TLinkList*tlinkList = (TLinkList *)list;

tlinkList->length = 0;

tlinkList->header.next =NULL;

}int LinkList_Length(LinkList*list)

{if (list ==NULL)

{return 0;

}

TLinkList*tlinkList = (TLinkList *)list;return tlinkList->length;

}int LinkList_Insert(LinkList* list, LinkListNode* node, intpos)

{

LinkListNode*pre, *cur;inti;if (list == NULL || node ==NULL)

{return -1;

}//校验下标

if (pos<0)

{return -2;

}

TLinkList*tlinkList = (TLinkList *)list;if (pos>tlinkList->length - 1)

{

pos= tlinkList->length;

}

pre= (LinkListNode *)list;//初始化指向头节点

cur = tlinkList->header.next;//初始化指向第一个节点,如果空链表指向空

for (i = 0; i < pos; i++)

{

pre=cur;

cur= cur->next;//最终让当前指针指向要插入的位置

}

pre->next =node;

node->next =cur;

tlinkList->length++;return 0;

}

LinkListNode* LinkList_Get(LinkList* list, intpos)

{

LinkListNode*pre, *cur;inti;if (list ==NULL)

{returnNULL;

}

TLinkList*tlinkList = (TLinkList *)list;//校验下标

if (pos >= tlinkList->length || pos < 0)

{returnNULL;

}

cur= tlinkList->header.next;//初始化指向第一个节点,如果空链表指向空

for (i = 0; i < pos; i++)

{

cur= cur->next;

}returncur;

}

LinkListNode* LinkList_Delete(LinkList* list, intpos)

{

LinkListNode*pre, *cur;inti;if (list ==NULL)

{returnNULL;

}

TLinkList*tlinkList = (TLinkList *)list;//校验下标

if (pos >= tlinkList->length || pos < 0)

{returnNULL;

}

pre= (LinkListNode *)list;//初始化指向头节点

cur = tlinkList->header.next;//初始化指向第一个节点,如果空链表指向空

for (i = 0; i < pos; i++)

{

pre=cur;

cur= cur->next;

}

pre->next = cur->next;

LinkListNode* curnode =cur;

tlinkList->length--;returncurnode;

}

测试代码

#include "stdio.h"#include"stdlib.h"#include"linklist.h"typedefstruct_Teacher

{

LinkListNode listNode;intage;char name[50];

}Teacher;voidmain()

{

LinkList*linkList;

Teacher t1, t2, t3;intlen;inti;

linkList=LinkList_Create();

t1.age= 11;

t2.age= 22;

t3.age= 33;

LinkList_Insert(linkList, (LinkListNode*)&t1, 0);

LinkList_Insert(linkList, (LinkListNode*)&t2, 0);

LinkList_Insert(linkList, (LinkListNode*)&t3, 0);

len=LinkList_Length(linkList);for (i = 0; i < len; i++)

{

Teacher* t = (Teacher *)LinkList_Get(linkList, i);

printf("cur teacher age=%d", t->age);

}

LinkList_Delete(linkList,0);

LinkList_Delete(linkList,1);

len=LinkList_Length(linkList);for (i = 0; i < len; i++)

{

Teacher* t = (Teacher *)LinkList_Get(linkList, i);

printf("cur teacher age=%d", t->age);

}

system("pause");

}

接下来,如果我们有新的结构体,只要在测试代码那边做修改,而不需要动我们的核心代码了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值