一、单向链表的C语言实现
2026/6/16 0:06:50 网站建设 项目流程

一、单向链表的C语言实现

链表作为一种基本的数据结构在程序开发过程当中经常会使用到。对C语言来说链表的实现主要依靠结构体和指针,所以本文相关内容和程序需要有C语言当中指针和结构体的基础。

链表是一种线性存储数据的结构,存储内容在逻辑上连续的,在物理上却不一定连续。单向链表的组成包括一个链表头(head)和若干链表元素(node),对链表的基本操作其实就是增、删、改、查。

首先说说单向链表的C语言实现方法。为了实现一个单向链表,首先定义一个结构体:

/* 定义一个表示链表的结构体指针 /

struct list {

int id; / 标识这个元素方便查找 /

char data; / 链表中包含的元素 */

struct list next; / 指向下一个链表的指针 */

};

下面来编写程序实现一个链表的基本操作。该程序的功能是首先分配若干个链表元素(node),然后对这些链表元素进行赋初值,赋完初值之后将这些链表元素依次加入到链表当中,最后把这些元素的data字段依次打印出来。(注意 :本程序实现的链表头结点(head)当中是存放数据的;为了保证每一个元素的id字段都不相同,所以定义了一个全局静态数据成员list_id;使用linux下的gcc进行编译)。程序如下:

/* 包含的头文件 */

#include

#include

/* 定义一个表示链表的结构体指针 /

struct list {

int id; / 标识这个元素方便查找 /

char data; / 链表中包含的元素 */

struct list next; / 指向下一个链表的指针 */

};

/* 定义一个链表头部 */

static struct list *list_head = NULL;

/* 为了保证每一个链表元素的id不同,特意把id定义成一个全局静态变量 */

static int list_id = 0;

/** 将指定元素插入到聊表尾部

/** 遍历一个链表,打印链表中每个元素所包含的数据

/* 主函数,程序的入口 */

int main(int argc, char *argv)

int i = 0;

struct list *lists = NULL;

/* 分配10个元素 */ lists = malloc(sizeof(struct list) * 10); if(NULL == lists) { printf("malloc error!\n"); return -1; } /* 将分配的10个元素依次填充数据并加入到链表当中 */ for(i = 0; i < 10; i++) { lists[i].id = list_id++; sprintf(lists[i].data, "TECH-PRO - %d", i); list_add(&list_head, &lists[i]); } /* 遍历链表,把链表中每个元素的信息都打印出来 */ list_print(&list_head); return 0; }

二、单向链表的基本操作

链表的基本操作其实就是对链表中元素的操作。链表的基本操作包括链表中结点元素的添加、删除、修改和查看,简单来说就是增、删、改、查。

2.1 单向链表中元素添加

在链表中添加元素时首先判断链表是否为空,为空时直接把要添加的元素赋值给链表头部,否者就要对链表进行遍历找到下一个为空的结点,然后把元素插入到链表尾部。

实现链表插入的程序代码:

/** 将指定元素插入到聊表尾部 * head : 表示要插入元素的链表的头部的地址 * list : 表示要插入到链表中的元素 */ static void list_add(struct list **head, struct list *list) { struct list *temp; /* 判断链表是否为空 */ if(NULL == *head) { /* 为空 */ *head = list; (*head)->next = NULL; } else { /* 不为空 */ temp = *head; while(temp) { if(NULL == temp->next) { temp->next = list; list->next = NULL; } temp = temp->next; } } }

在main函数中田间如下代码:

struct list temp_list; /* 填充这个结构体并加入链表当中 */ temp_list.id = list_id++; sprintf(temp_list.data, "temp_list"); list_add(&list_head, &temp_list);

2.2 在单向链表中删除元素

在链表删除一个元素结点是链表基本操作中相对复杂的。首先需要判断链表是否为空,当链表不为空时,要再次判断要删除的元素是否是头结点(head),如果是直接将下一个元素赋值给头结点,不过不是就需要遍历整个链表找到要删除的结点元素。(注:本算法实现的删除是通过对元素结点的id字段进行的)。

删除链表结点的程序代码:

/** 将指定元素从链表尾部删除 * head : 表示要删除元素的链表的头部的地址 * id : 表示要删除元素的标识 * 返回值 : 0-成功,-1-失败 */ static int list_del(struct list **head, int id) { struct list *temp, *p; temp = *head; if(NULL == temp) { /* 链表为空 */ printf("链表为空!\n"); return -1; } else { /* 判断匹配的元素是否为链表头部的元素 */ if(id == temp->id) /* 是链表头部 */ { *head = temp->next; return 0; } else /* 不是链表头部 */ { while(temp->next) { p = temp; temp = temp->next; if(id == temp->id) { p->next = temp->next; return 0; } } return -1; } } return -1; }

在main函数中添加如下代码:die.yuhewh.Com.Cn
vyq.yuhewh.Com.Cn
zgu.yuhewh.Com.Cn
mz.yuhewh.Com.Cn
bcz.yuhewh.Com.Cn
fnz.yuhewh.Com.Cn
pp.yuhewh.Com.Cn
tkj.yuhewh.Com.Cn
qhl.yuhewh.Com.Cn
rq.yuhewh.Com.Cn
nvx.yuhewh.Com.Cn
ah.yuhewh.Com.Cn
gaj.yuhewh.Com.Cn
ia.yuhewh.Com.Cn
mmw.yuhewh.Com.Cn
bob.yuhewh.Com.Cn
jkp.yuhewh.Com.Cn
cxk.yuhewh.Com.Cn
ga.yuhewh.Com.Cn
vm.yuhewh.Com.Cn
btk.yuhewh.Com.Cn
fgo.yuhewh.Com.Cn
stn.yuhewh.Com.Cn
cad.yuhewh.Com.Cn
fbo.yuhewh.Com.Cn
mg.yuhewh.Com.Cn
em.yuhewh.Com.Cn
hqb.yuhewh.Com.Cn
izs.yuhewh.Com.Cn
otp.yuhewh.Com.Cn
nwh.yuhewh.Com.Cn
nhw.yuhewh.Com.Cn
sd.yuhewh.Com.Cn
en.yuhewh.Com.Cn
zp.yuhewh.Com.Cn
qbx.yuhewh.Com.Cn
anc.yuhewh.Com.Cn
qhk.yuhewh.Com.Cn
hm.yuhewh.Com.Cn
rbm.yuhewh.Com.Cn
gk.yuhewh.Com.Cn
srl.yuhewh.Com.Cn
ep.yuhewh.Com.Cn
ind.yuhewh.Com.Cn
zlc.yuhewh.Com.Cn
df.yuhewh.Com.Cn
ity.yuhewh.Com.Cn
yzt.yuhewh.Com.Cn
aus.yuhewh.Com.Cn
def.yuhewh.Com.Cn
bj.yuhewh.Com.Cn
in.yuhewh.Com.Cn
tl.yuhewh.Com.Cn
fl.yuhewh.Com.Cn
iby.yuhewh.Com.Cn
bce.yuhewh.Com.Cn
sdj.yuhewh.Com.Cn
vy.yuhewh.Com.Cn
kc.yuhewh.Com.Cn
mth.yuhewh.Com.Cn
rcd.yuhewh.Com.Cn
yi.yuhewh.Com.Cn
jrg.yuhewh.Com.Cn
brs.yuhewh.Com.Cn
lq.yuhewh.Com.Cn
hng.yuhewh.Com.Cn
xmy.yuhewh.Com.Cn
nzg.yuhewh.Com.Cn
al.yuhewh.Com.Cn
nk.yuhewh.Com.Cn
bs.yuhewh.Com.Cn
knw.yuhewh.Com.Cn
ayz.yuhewh.Com.Cn
bf.yuhewh.Com.Cn
woi.yuhewh.Com.Cn
tpw.yuhewh.Com.Cn
ur.yuhewh.Com.Cn
lfw.yuhewh.Com.Cn
xkf.yuhewh.Com.Cn
kkx.yuhewh.Com.Cn
hi.yuhewh.Com.Cn
bo.yuhewh.Com.Cn
kjq.yuhewh.Com.Cn
xae.yuhewh.Com.Cn
lqj.yuhewh.Com.Cn
jr.yuhewh.Com.Cn
wrq.yuhewh.Com.Cn
rt.yuhewh.Com.Cn
tpu.yuhewh.Com.Cn
yr.yuhewh.Com.Cn
lca.yuhewh.Com.Cn
oqv.yuhewh.Com.Cn
hua.yuhewh.Com.Cn
ujr.yuhewh.Com.Cn
dj.yuhewh.Com.Cn
vsk.yuhewh.Com.Cn
hrb.yuhewh.Com.Cn
ac.yuhewh.Com.Cn
myy.yuhewh.Com.Cn
fa.yuhewh.Com.Cn
yj.yuhewh.Com.Cn
qt.yuhewh.Com.Cn
bja.yuhewh.Com.Cn
ohi.yuhewh.Com.Cn
qvw.yuhewh.Com.Cn
bk.yuhewh.Com.Cn
amd.yuhewh.Com.Cn
cvw.yuhewh.Com.Cn
tsw.yuhewh.Com.Cn
zw.yuhewh.Com.Cn
zxp.yuhewh.Com.Cn
auq.yuhewh.Com.Cn
xgk.yuhewh.Com.Cn
ss.yuhewh.Com.Cn
of.yuhewh.Com.Cn
uv.yuhewh.Com.Cn
cjg.yuhewh.Com.Cn
czh.yuhewh.Com.Cn
vyl.yuhewh.Com.Cn
psw.yuhewh.Com.Cn
kfa.yuhewh.Com.Cn
qm.yuhewh.Com.Cn
qlq.yuhewh.Com.Cn
zva.yuhewh.Com.Cn
ipc.yuhewh.Com.Cn
jki.yuhewh.Com.Cn
hix.yuhewh.Com.Cn
zjx.yuhewh.Com.Cn
wn.yuhewh.Com.Cn
wpu.yuhewh.Com.Cn
ec.yuhewh.Com.Cn
aa.yuhewh.Com.Cn
yln.yuhewh.Com.Cn
qfb.yuhewh.Com.Cn
lw.yuhewh.Com.Cn
dgm.yuhewh.Com.Cn
ny.yuhewh.Com.Cn
kd.yuhewh.Com.Cn
ecN.yuhewh.Com.Cn
esl.yuhewh.Com.Cn
zkl.yuhewh.Com.Cn
ms.yuhewh.Com.Cn
zm.yuhewh.Com.Cn
hyv.yuhewh.Com.Cn
fv.yuhewh.Com.Cn
lac.yuhewh.Com.Cn
qsh.yuhewh.Com.Cn
qrz.yuhewh.Com.Cn
vo.yuhewh.Com.Cn
lbz.yuhewh.Com.Cn
xd.yuhewh.Com.Cn
el.yuhewh.Com.Cn
pk.yuhewh.Com.Cn
ub.yuhewh.Com.Cn
cq.yuhewh.Com.Cn
wb.yuhewh.Com.Cn
ekf.yuhewh.Com.Cn
oy.yuhewh.Com.Cn
tlt.yuhewh.Com.Cn
prf.yuhewh.Com.Cn
zx.yuhewh.Com.Cn
fn.yuhewh.Com.Cn
lnx.yuhewh.Com.Cn
xvq.yuhewh.Com.Cn
jos.yuhewh.Com.Cn
ji.yuhewh.Com.Cn
goa.yuhewh.Com.Cn
ufv.yuhewh.Com.Cn
jn.yuhewh.Com.Cn
nlw.yuhewh.Com.Cn
wan.yuhewh.Com.Cn
jgi.yuhewh.Com.Cn
daf.yuhewh.Com.Cn
eb.yuhewh.Com.Cn
zci.yuhewh.Com.Cn
huv.yuhewh.Com.Cn
opd.yuhewh.Com.Cn
dv.yuhewh.Com.Cn
ksl.yuhewh.Com.Cn
mc.yuhewh.Com.Cn
gd.yuhewh.Com.Cn
aqy.yuhewh.Com.Cn
blz.yuhewh.Com.Cn
lcr.yuhewh.Com.Cn
kzr.yuhewh.Com.Cn
sai.yuhewh.Com.Cn
fka.yuhewh.Com.Cn
arp.yuhewh.Com.Cn
vya.yuhewh.Com.Cn
dl.yuhewh.Com.Cn
huk.yuhewh.Com.Cn
ond.yuhewh.Com.Cn
ws.yuhewh.Com.Cn
qkl.yuhewh.Com.Cn
xz.yuhewh.Com.Cn
ku.yuhewh.Com.Cn
itd.yuhewh.Com.Cn
ysf.yuhewh.Com.Cn
hnv.yuhewh.Com.Cn
vdr.yuhewh.Com.Cn
bx.yuhewh.Com.Cn
vtk.yuhewh.Com.Cn
wkw.yuhewh.Com.Cn
rb.yuhewh.Com.Cn
hz.yuhewh.Com.Cn
dau.yuhewh.Com.Cn
dnj.yuhewh.Com.Cn
rdw.yuhewh.Com.Cn
rdx.yuhewh.Com.Cn
mvc.yuhewh.Com.Cn
oh.yuhewh.Com.Cn
mp.yuhewh.Com.Cn
svo.yuhewh.Com.Cn
uet.yuhewh.Com.Cn
vb.yuhewh.Com.Cn
pxj.yuhewh.Com.Cn
cps.yuhewh.Com.Cn
fhu.yuhewh.Com.Cn
neq.yuhewh.Com.Cn
vhv.yuhewh.Com.Cn
nek.yuhewh.Com.Cn
oue.yuhewh.Com.Cn
swv.yuhewh.Com.Cn
pq.yuhewh.Com.Cn
yc.yuhewh.Com.Cn
oow.yuhewh.Com.Cn
jef.yuhewh.Com.Cn
qb.yuhewh.Com.Cn
ir.yuhewh.Com.Cn
uqq.yuhewh.Com.Cn
wk.yuhewh.Com.Cn
ye.yuhewh.Com.Cn
rku.yuhewh.Com.Cn
bd.yuhewh.Com.Cn
iwj.yuhewh.Com.Cn
gii.yuhewh.Com.Cn
nvz.yuhewh.Com.Cn
ame.yuhewh.Com.Cn
ds.yuhewh.Com.Cn
oz.yuhewh.Com.Cn
sk.yuhewh.Com.Cn
kcu.yuhewh.Com.Cn
xn.yuhewh.Com.Cn
vk.yuhewh.Com.Cn
ido.yuhewh.Com.Cn
xfs.yuhewh.Com.Cn
cpw.yuhewh.Com.Cn
lak.yuhewh.Com.Cn
aos.yuhewh.Com.Cn
wip.yuhewh.Com.Cn
tlx.yuhewh.Com.Cn
po.yuhewh.Com.Cn
cN.yuhewh.Com.Cn
xvl.yuhewh.Com.Cn
ey.yuhewh.Com.Cn
lfq.yuhewh.Com.Cn
cbm.yuhewh.Com.Cn
pvy.yuhewh.Com.Cn
qsn.yuhewh.Com.Cn
qj.yuhewh.Com.Cn
xcv.yuhewh.Com.Cn
ch.yuhewh.Com.Cn
dvs.yuhewh.Com.Cn
aml.yuhewh.Com.Cn
ld.yuhewh.Com.Cn
qks.yuhewh.Com.Cn
zlg.yuhewh.Com.Cn
fko.yuhewh.Com.Cn
rqo.yuhewh.Com.Cn
gkl.yuhewh.Com.Cn
uo.yuhewh.Com.Cn
mk.yuhewh.Com.Cn
oti.yuhewh.Com.Cn
il.yuhewh.Com.Cn
enn.yuhewh.Com.Cn
oo.yuhewh.Com.Cn
fj.yuhewh.Com.Cn
swb.yuhewh.Com.Cn
jfz.yuhewh.Com.Cn
exb.yuhewh.Com.Cn
jf.yuhewh.Com.Cn
jhp.yuhewh.Com.Cn
thg.yuhewh.Com.Cn
erd.yuhewh.Com.Cn
wso.yuhewh.Com.Cn
dfo.yuhewh.Com.Cn
vsw.yuhewh.Com.Cn
pg.yuhewh.Com.Cn
pta.yuhewh.Com.Cn
qg.yuhewh.Com.Cn
yh.yuhewh.Com.Cn
rnu.yuhewh.Com.Cn
cwr.yuhewh.Com.Cn
nxe.yuhewh.Com.Cn
gtc.yuhewh.Com.Cn
amm.yuhewh.Com.Cn
dnf.yuhewh.Com.Cn
rs.yuhewh.Com.Cn
wg.yuhewh.Com.Cn
oni.yuhewh.Com.Cn

/* 删除链表中开始位置、中间位置、尾部的元素 */ list_del(&list_head, 0); list_del(&list_head, 5); list_del(&list_head, 10);

对程序进行编译结果:第0、5、10号元素都被删除:

2.3 在单向链表中修改指定的元素

在链表中修改元素,通过对链表中元素进行遍历,找到要修改的元素对其内容分进行修改即可,实现链表元素的修改是相对容易的。(注 :对要修改的元素的定位是通过id字段来完成的)

链表中修改元素的程序如下:

/** 将指定id的元素所定义的内容进行修改 * head : 表示要改变元素的链表的头部的地址 * id : 表示要改变元素的标识 * content : 表示要改变的内容 * 返回值 : 0-成功,-1-失败 */ static int list_chg(struct list **head, int id, char *content) { struct list *temp; temp = *head; /* 将链表的头部赋值给临时聊表变量 */ while(temp) /* 对链表进行轮询 */ { if(id == temp->id) { memset(temp->data, 0, sizeof(temp->data)); sprintf(temp->data, "%s", content); temp->data[strlen(content)] = '\0'; return 0; } temp = temp->next; } return -1; }

在main函数中添加如下代码:

/* 改变id为4的元素所对应的值为 "change!!!" */ list_chg(&list_head, 4, "change!!!");

2.4 对单向链表的元素进行查询操作

在链表中查询一个元素,根据链表头部对链表进行遍历即可。

链表中查询的程序代码:

/** 将指定id的元素所定义的内容进行查找 * head : 表示要查询元素的链表的头部的地址 * id : 表示要查询元素的标识 * 返回值 : 0-成功,-1-失败 */ static int list_query(struct list **head, int id) { struct list *temp; temp = *head; /* 将链表的头部赋值给临时聊表变量 */ while(temp) /* 对链表进行轮询 */ { if(id == temp->id) { printf("list %d : %s\n", temp->id, temp->data); return 0; } temp = temp->next; } /* 没有找到元素 */ printf("not finding!\n"); return -1; }

附录:单向链表的基本操作完整的程序。

/* 包含的头文件 */ #include #include #include /* 定义一个表示链表的结构体指针 */ struct list { int id; /* 标识这个元素方便查找 */ char data[20]; /* 链表中包含的元素 */ struct list *next; /* 指向下一个链表的指针 */ }; /* 定义一个链表头部 */ static struct list *list_head = NULL; /* 为了保证每一个链表元素的id不同,特意把id定义成一个全局静态变量 */ static int list_id = 0; /** 将指定元素插入到链表尾部 * head : 表示要插入元素的链表的头部的地址 * list : 表示要插入到链表中的元素 */ static void list_add(struct list **head, struct list *list) { struct list *temp; /* 判断链表是否为空 */ if(NULL == *head) { /* 为空 */ *head = list; (*head)->next = NULL; } else { /* 不为空 */ temp = *head; while(temp) { if(NULL == temp->next) { temp->next = list; list->next = NULL; } temp = temp->next; } } } /** 遍历一个链表,打印链表中每个元素所包含的数据 * head : 表示要遍历的链表的头部的指针 */ static void list_print(struct list **head) { struct list *temp; temp = *head; printf("list information :\n"); while(temp) { printf("\tlist %d : %s\n", temp->id, temp->data); temp = temp->next; } } /** 将指定元素从链表尾部删除 * head : 表示要删除元素的链表的头部的地址 * id : 表示要删除元素的标识 * 返回值 : 0-成功,-1-失败 */ static int list_del(struct list **head, int id) { struct list *temp, *p; temp = *head; if(NULL == temp) { /* 链表为空 */ printf("链表为空!\n"); return -1; } else { /* 判断匹配的元素是否为链表头部的元素 */ if(id == temp->id) /* 是链表头部 */ { *head = temp->next; return 0; } else /* 不是链表头部 */ { while(temp->next) { p = temp; temp = temp->next; if(id == temp->id) { p->next = temp->next; return 0; } } return -1; } } return -1; } /** 将指定id的元素所定义的内容进行修改 * head : 表示要改变元素的链表的头部的地址 * id : 表示要改变元素的标识 * content : 表示要改变的内容 * 返回值 : 0-成功,-1-失败 */ static int list_chg(struct list **head, int id, char *content) { struct list *temp; temp = *head; /* 将链表的头部赋值给临时聊表变量 */ while(temp) /* 对链表进行轮询 */ { if(id == temp->id) { memset(temp->data, 0, sizeof(temp->data)); sprintf(temp->data, "%s", content); temp->data[strlen(content)] = '\0'; return 0; } temp = temp->next; } return -1; } /** 将指定id的元素所定义的内容进行查找 * head : 表示要查询元素的链表的头部的地址 * id : 表示要查询元素的标识 * 返回值 : 0-成功,-1-失败 */ static int list_query(struct list **head, int id) { struct list *temp; temp = *head; /* 将链表的头部赋值给临时聊表变量 */ while(temp) /* 对链表进行轮询 */ { if(id == temp->id) { printf("list %d : %s\n", temp->id, temp->data); return 0; } temp = temp->next; } /* 没有找到元素 */ printf("not finding!\n"); return -1; } /* 主函数,程序的入口 */ int main(int argc, char *argv[]) { int i = 0; struct list *lists = NULL; struct list temp_list; /* 分配10个元素 */ lists = malloc(sizeof(struct list) * 10); if(NULL == lists) { printf("malloc error!\n"); return -1; } /* 将分配的10个元素依次填充数据并加入到链表当中 */ for(i = 0; i < 10; i++) { lists[i].id = list_id++; sprintf(lists[i].data, "TECH-PRO - %d", i); list_add(&list_head, &lists[i]); } /* 填充这个结构体并加入链表当中 */ temp_list.id = list_id++; sprintf(temp_list.data, "temp_list"); list_add(&list_head, &temp_list); /* 删除链表中开始位置、中间位置、尾部的元素 */ list_del(&list_head, 0); list_del(&list_head, 5); list_del(&list_head, 10); /* 改变id为4的元素所对应的值为 "change!!!" */ list_chg(&list_head, 4, "change!!!"); /* 查询链表中id为4的元素结点的内容 */ list_query(&list_head, 4); return 0; }

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询