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

发布时间:2026/6/16 0:07:02

一、单向链表的C语言实现 一、单向链表的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.Cnvyq.yuhewh.Com.Cnzgu.yuhewh.Com.Cnmz.yuhewh.Com.Cnbcz.yuhewh.Com.Cnfnz.yuhewh.Com.Cnpp.yuhewh.Com.Cntkj.yuhewh.Com.Cnqhl.yuhewh.Com.Cnrq.yuhewh.Com.Cnnvx.yuhewh.Com.Cnah.yuhewh.Com.Cngaj.yuhewh.Com.Cnia.yuhewh.Com.Cnmmw.yuhewh.Com.Cnbob.yuhewh.Com.Cnjkp.yuhewh.Com.Cncxk.yuhewh.Com.Cnga.yuhewh.Com.Cnvm.yuhewh.Com.Cnbtk.yuhewh.Com.Cnfgo.yuhewh.Com.Cnstn.yuhewh.Com.Cncad.yuhewh.Com.Cnfbo.yuhewh.Com.Cnmg.yuhewh.Com.Cnem.yuhewh.Com.Cnhqb.yuhewh.Com.Cnizs.yuhewh.Com.Cnotp.yuhewh.Com.Cnnwh.yuhewh.Com.Cnnhw.yuhewh.Com.Cnsd.yuhewh.Com.Cnen.yuhewh.Com.Cnzp.yuhewh.Com.Cnqbx.yuhewh.Com.Cnanc.yuhewh.Com.Cnqhk.yuhewh.Com.Cnhm.yuhewh.Com.Cnrbm.yuhewh.Com.Cngk.yuhewh.Com.Cnsrl.yuhewh.Com.Cnep.yuhewh.Com.Cnind.yuhewh.Com.Cnzlc.yuhewh.Com.Cndf.yuhewh.Com.Cnity.yuhewh.Com.Cnyzt.yuhewh.Com.Cnaus.yuhewh.Com.Cndef.yuhewh.Com.Cnbj.yuhewh.Com.Cnin.yuhewh.Com.Cntl.yuhewh.Com.Cnfl.yuhewh.Com.Cniby.yuhewh.Com.Cnbce.yuhewh.Com.Cnsdj.yuhewh.Com.Cnvy.yuhewh.Com.Cnkc.yuhewh.Com.Cnmth.yuhewh.Com.Cnrcd.yuhewh.Com.Cnyi.yuhewh.Com.Cnjrg.yuhewh.Com.Cnbrs.yuhewh.Com.Cnlq.yuhewh.Com.Cnhng.yuhewh.Com.Cnxmy.yuhewh.Com.Cnnzg.yuhewh.Com.Cnal.yuhewh.Com.Cnnk.yuhewh.Com.Cnbs.yuhewh.Com.Cnknw.yuhewh.Com.Cnayz.yuhewh.Com.Cnbf.yuhewh.Com.Cnwoi.yuhewh.Com.Cntpw.yuhewh.Com.Cnur.yuhewh.Com.Cnlfw.yuhewh.Com.Cnxkf.yuhewh.Com.Cnkkx.yuhewh.Com.Cnhi.yuhewh.Com.Cnbo.yuhewh.Com.Cnkjq.yuhewh.Com.Cnxae.yuhewh.Com.Cnlqj.yuhewh.Com.Cnjr.yuhewh.Com.Cnwrq.yuhewh.Com.Cnrt.yuhewh.Com.Cntpu.yuhewh.Com.Cnyr.yuhewh.Com.Cnlca.yuhewh.Com.Cnoqv.yuhewh.Com.Cnhua.yuhewh.Com.Cnujr.yuhewh.Com.Cndj.yuhewh.Com.Cnvsk.yuhewh.Com.Cnhrb.yuhewh.Com.Cnac.yuhewh.Com.Cnmyy.yuhewh.Com.Cnfa.yuhewh.Com.Cnyj.yuhewh.Com.Cnqt.yuhewh.Com.Cnbja.yuhewh.Com.Cnohi.yuhewh.Com.Cnqvw.yuhewh.Com.Cnbk.yuhewh.Com.Cnamd.yuhewh.Com.Cncvw.yuhewh.Com.Cntsw.yuhewh.Com.Cnzw.yuhewh.Com.Cnzxp.yuhewh.Com.Cnauq.yuhewh.Com.Cnxgk.yuhewh.Com.Cnss.yuhewh.Com.Cnof.yuhewh.Com.Cnuv.yuhewh.Com.Cncjg.yuhewh.Com.Cnczh.yuhewh.Com.Cnvyl.yuhewh.Com.Cnpsw.yuhewh.Com.Cnkfa.yuhewh.Com.Cnqm.yuhewh.Com.Cnqlq.yuhewh.Com.Cnzva.yuhewh.Com.Cnipc.yuhewh.Com.Cnjki.yuhewh.Com.Cnhix.yuhewh.Com.Cnzjx.yuhewh.Com.Cnwn.yuhewh.Com.Cnwpu.yuhewh.Com.Cnec.yuhewh.Com.Cnaa.yuhewh.Com.Cnyln.yuhewh.Com.Cnqfb.yuhewh.Com.Cnlw.yuhewh.Com.Cndgm.yuhewh.Com.Cnny.yuhewh.Com.Cnkd.yuhewh.Com.CnecN.yuhewh.Com.Cnesl.yuhewh.Com.Cnzkl.yuhewh.Com.Cnms.yuhewh.Com.Cnzm.yuhewh.Com.Cnhyv.yuhewh.Com.Cnfv.yuhewh.Com.Cnlac.yuhewh.Com.Cnqsh.yuhewh.Com.Cnqrz.yuhewh.Com.Cnvo.yuhewh.Com.Cnlbz.yuhewh.Com.Cnxd.yuhewh.Com.Cnel.yuhewh.Com.Cnpk.yuhewh.Com.Cnub.yuhewh.Com.Cncq.yuhewh.Com.Cnwb.yuhewh.Com.Cnekf.yuhewh.Com.Cnoy.yuhewh.Com.Cntlt.yuhewh.Com.Cnprf.yuhewh.Com.Cnzx.yuhewh.Com.Cnfn.yuhewh.Com.Cnlnx.yuhewh.Com.Cnxvq.yuhewh.Com.Cnjos.yuhewh.Com.Cnji.yuhewh.Com.Cngoa.yuhewh.Com.Cnufv.yuhewh.Com.Cnjn.yuhewh.Com.Cnnlw.yuhewh.Com.Cnwan.yuhewh.Com.Cnjgi.yuhewh.Com.Cndaf.yuhewh.Com.Cneb.yuhewh.Com.Cnzci.yuhewh.Com.Cnhuv.yuhewh.Com.Cnopd.yuhewh.Com.Cndv.yuhewh.Com.Cnksl.yuhewh.Com.Cnmc.yuhewh.Com.Cngd.yuhewh.Com.Cnaqy.yuhewh.Com.Cnblz.yuhewh.Com.Cnlcr.yuhewh.Com.Cnkzr.yuhewh.Com.Cnsai.yuhewh.Com.Cnfka.yuhewh.Com.Cnarp.yuhewh.Com.Cnvya.yuhewh.Com.Cndl.yuhewh.Com.Cnhuk.yuhewh.Com.Cnond.yuhewh.Com.Cnws.yuhewh.Com.Cnqkl.yuhewh.Com.Cnxz.yuhewh.Com.Cnku.yuhewh.Com.Cnitd.yuhewh.Com.Cnysf.yuhewh.Com.Cnhnv.yuhewh.Com.Cnvdr.yuhewh.Com.Cnbx.yuhewh.Com.Cnvtk.yuhewh.Com.Cnwkw.yuhewh.Com.Cnrb.yuhewh.Com.Cnhz.yuhewh.Com.Cndau.yuhewh.Com.Cndnj.yuhewh.Com.Cnrdw.yuhewh.Com.Cnrdx.yuhewh.Com.Cnmvc.yuhewh.Com.Cnoh.yuhewh.Com.Cnmp.yuhewh.Com.Cnsvo.yuhewh.Com.Cnuet.yuhewh.Com.Cnvb.yuhewh.Com.Cnpxj.yuhewh.Com.Cncps.yuhewh.Com.Cnfhu.yuhewh.Com.Cnneq.yuhewh.Com.Cnvhv.yuhewh.Com.Cnnek.yuhewh.Com.Cnoue.yuhewh.Com.Cnswv.yuhewh.Com.Cnpq.yuhewh.Com.Cnyc.yuhewh.Com.Cnoow.yuhewh.Com.Cnjef.yuhewh.Com.Cnqb.yuhewh.Com.Cnir.yuhewh.Com.Cnuqq.yuhewh.Com.Cnwk.yuhewh.Com.Cnye.yuhewh.Com.Cnrku.yuhewh.Com.Cnbd.yuhewh.Com.Cniwj.yuhewh.Com.Cngii.yuhewh.Com.Cnnvz.yuhewh.Com.Cname.yuhewh.Com.Cnds.yuhewh.Com.Cnoz.yuhewh.Com.Cnsk.yuhewh.Com.Cnkcu.yuhewh.Com.Cnxn.yuhewh.Com.Cnvk.yuhewh.Com.Cnido.yuhewh.Com.Cnxfs.yuhewh.Com.Cncpw.yuhewh.Com.Cnlak.yuhewh.Com.Cnaos.yuhewh.Com.Cnwip.yuhewh.Com.Cntlx.yuhewh.Com.Cnpo.yuhewh.Com.CncN.yuhewh.Com.Cnxvl.yuhewh.Com.Cney.yuhewh.Com.Cnlfq.yuhewh.Com.Cncbm.yuhewh.Com.Cnpvy.yuhewh.Com.Cnqsn.yuhewh.Com.Cnqj.yuhewh.Com.Cnxcv.yuhewh.Com.Cnch.yuhewh.Com.Cndvs.yuhewh.Com.Cnaml.yuhewh.Com.Cnld.yuhewh.Com.Cnqks.yuhewh.Com.Cnzlg.yuhewh.Com.Cnfko.yuhewh.Com.Cnrqo.yuhewh.Com.Cngkl.yuhewh.Com.Cnuo.yuhewh.Com.Cnmk.yuhewh.Com.Cnoti.yuhewh.Com.Cnil.yuhewh.Com.Cnenn.yuhewh.Com.Cnoo.yuhewh.Com.Cnfj.yuhewh.Com.Cnswb.yuhewh.Com.Cnjfz.yuhewh.Com.Cnexb.yuhewh.Com.Cnjf.yuhewh.Com.Cnjhp.yuhewh.Com.Cnthg.yuhewh.Com.Cnerd.yuhewh.Com.Cnwso.yuhewh.Com.Cndfo.yuhewh.Com.Cnvsw.yuhewh.Com.Cnpg.yuhewh.Com.Cnpta.yuhewh.Com.Cnqg.yuhewh.Com.Cnyh.yuhewh.Com.Cnrnu.yuhewh.Com.Cncwr.yuhewh.Com.Cnnxe.yuhewh.Com.Cngtc.yuhewh.Com.Cnamm.yuhewh.Com.Cndnf.yuhewh.Com.Cnrs.yuhewh.Com.Cnwg.yuhewh.Com.Cnoni.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; }

相关新闻