一、链表基础

链表是一种常见的数据结构,其中运用到了结构体指针,链表可以实现动态存储分配,换而言之,链表是一个功能强大的数组,可以在某个节点定义多种数据类型,可以实现任意的添加,删除,插入节点等。链表分为两类,一种是有头节点的链表,另一种是无头节点的链表。头节点没有数据域的,其他每个节点都有两部分,一是数据域,二是指针域。下面对单向链表进行详细介绍。
操作包括:链表的创建、修改、删除、插入等。最后以一个在嵌入式的应用结束。

1、有头结点的单向链表

1、链表定义

typedef struct node_st
{datatype data;struct node_st *next;
}list;

2、链表创建

/*** @brief  链表的创建* @param  无* @retval 返回创建成功的链表首地址*/
list* list_creat()
{/*创建一个带头节点的单链表*/list *me;/*分配内存空间*/me = malloc(sizeof(*me));if (me == NULL)return NULL;/*数据域不管,指针域设置为空指针*/me->next = NULL;return me;
}

3、链表插入

链表插入是找到待插入节点位置的前驱结点

/*** @brief  链表的位置插入* @param  链表名称,插入位置,插入数据* @retval 返回0表示插入成功*/
int list_insert_at(list *me,int i,datatype *data)
{int j = 0;/*创建一个链表,存放me*/list *node = me,*newnode;/*如果插入位置小于0,返回错误*/if (i<0)return -1;/*node指针一个个向后找,直到找到了某一个节点*/while (j<i&& node != NULL){node = node->next;j++;}/*如果node指针不为空,表示找到一个有效位置作为插入,获得的是待插入位置的前驱节点*//*单向链表只能单向移动,找不到后继节点的前驱指针*/if (node){newnode = malloc(sizeof(*newnode));if (newnode == NULL)return -2;/*使用新的newnode存放需要插入的数据*/newnode->data = *data;/*首先设置指针为空*/newnode->next = NULL;/*新节点的next指针等于旧节点的next指针(旧节点的后继节点)*/newnode->next = node->next;/*旧节点的next指向新节点的本身*/node->next = newnode;return 0;   }/*表示第i个位置是不合法的*/elsereturn -3;
} 

4、链表遍历

/*** @brief  链表的遍历* @param  链表指针* @retval 返回为空*/
void list_display(list*me)
{list *node = me->next;/*如果链表为空,返回*/if(list_isempty(me) == 0){return;}/*链表不为空,打印链表数据*/while (node!=NULL){printf("%d ",node->data);node = node->next;}printf("\n");return ;
}

5、链表顺序插入

链表插入是找到待插入节点位置的前驱结点

/*** @brief  链表的顺序插入* @param  链表指针,待插入数据* @retval 返回插入状态*/
int list_order_insert(list *me,datatype *data)
{list *p = me,*q;/*p插入节点的前驱位置*/while (p->next && p->next->data<*data)/*继续向后移动*/p = p->next;/*申请内存空间*/q = malloc(sizeof(*q));if (q == NULL)return -1;/*存放数据*/q->data = *data;/*插入数据*/q->next = p->next;/*插入成功*/p->next = q;return 0;
}

6、链表指定位置删除

指定位置删除是找到待删除节点位置的前驱结点

/*** @brief  链表的位置删除* @param  链表指针,待删除位置,待删除数据* @retval 返回删除状态*/
int list_delete_at(list*me,int i,datatype *data)
{int j = 0;list *p = me,*q;/*初始化设置数据为-1,观察返回值的状态*/*data = -1;/*删除位置错误*/if (i<0){return -1;}/*当j<i,并且p不为空,一直向后找*/ while (j<i&&p){p = p->next;j++;}/*当指针p不为空,表示找到了*/if (p){/* q指向p的后继节点 */q = p->next;/* p的后继节点指向q的后继节点 */p->next = q->next;*data = q->data;/*释放指针q*/free(q);q = NULL;return 0;}/*表示没有找到*/else{return -2;}
}

7、链表的数据删除

删除是找到待删除节点位置的前驱结点

/*** @brief  链表的数据删除* @param  链表指针,待删除数据* @retval 返回删除状态*/
int list_delete(list *me,datatype *data)
{list *p = me,*q;/*一直寻找需要删除的数据,知道找到为止*/while (p->next && p->next->data != *data){p=p->next;}if (p->next == NULL )return -1;else{/*保存p的后继节点*/q = p->next;/*p的后继节点保存q的后继节点*/p->next = q->next;/*释放q*/free(q);q = NULL;}}

8、判断链表是否为空

/*** @brief  判断链表释放为空* @param  链表指针* @retval 返回删除状态,0为空,1非空*/
int list_isempty(list *me)
{if (me->next == NULL)    return 0;return 1;
}

9、链表的销毁

/*** @brief  链表的销毁* @param  链表指针* @retval 空*/
void list_destory(list *me)
{list *node,*next;/* node 指向 me的后继节点,逐个释放node */for(node = me->next;node!=NULL;node = next){next = node->next;free(node);}free(me);return;
}

10、初始化有头链表示例

/*链表的创建*/list *l;int i,err;datatype arr[] = {12,9,23,2,34,6,45};l = list_creat();if (l == NULL){exit(1);}/*链表的初始化*/for (i = 0; i < sizeof(arr)/sizeof(*arr); i++){if(list_order_insert(l,&arr[i]))//if(list_insert_at(l,0,&arr[i]))exit(1);}

2、无头结点的单向链表

1、链表插入

/*** @brief  链表插入* @param  待插入数据* @retval 插入状态*/
/*二级指针传参*/
int list_insert(struct node_st **list,struct score_st *data)
{struct node_st *new;/* 开辟内存空间并且判断*/new = malloc(sizeof(*new));if (new == NULL)return -1;/*新节点的数据保存*/new->data = *data;new->next = NULL;/*找到并且保存list的指针*/new->next = *list;/* list 就是新节点 */*list = new;return 0;
}

2、链表删除

/*** @brief  链表删除第一个有效节点* @param  链表指针* @retval 删除状态*/
int list_delete(struct node_st **list)
{struct node_st *cur;if (*list == NULL)return -1;/*保存当前节点*/cur = *list;/*当前节点指向下一个节点*/*list = (*list)->next;   free(cur);return 0;
}

3、链表查找

/*** @brief  链表查找* @param  链表,位置* @retval 链表指针*/
struct score_st *list_find(struct node_st*list,int id)
{struct node_st *cur;/*循环查找,查看是否找到*/for (cur  = list; cur != NULL;cur = cur->next){/*如果找到id*/if(cur->data.id == id)return &cur->data;}/*没有找到id,返回NULL*/return NULL;
}

4、链表销毁

/*** @brief  链表销毁* @param  链表指针* @retval 无*/
void list_destory(struct node_st* list)
{struct node_st *cur;if (list == NULL)return;/*逐个释放*/for (cur = list;cur!= NULL;cur = list){list = cur->next;free(cur);}
}

5、初始化无头链表示例

/*定义数据结构*/
struct score_st
{int id;char name[NAMESIZE];int math;int chinese;
};struct  node_st
{struct score_st data;struct node_st *next;
};/*初始化无头链表*/for ( i = 0; i < 7; i++){tmp.id = i;snprintf(tmp.name,NAMESIZE,"std %d",i);tmp.math = rand()%100;tmp.chinese = rand()%100;ret = list_insert(&list,&tmp);  if (ret != 0)exit(1);}

数据结构—单向链表(详解)相关推荐

  1. 数据结构之链表详解(2)——双向链表

    目录 前言 一.双向链表 A.双向链表的含义 B.双向链表的实现 1.双向链表的结构 2.链表的初始化 初始化图解: 函数代码: 3.动态申请节点函数 函数代码: 4.打印双向链表函数 函数代码: 5 ...

  2. python链表值讲解_python数据结构之链表详解

    python数据结构之链表详解 数据结构是计算机科学必须掌握的一门学问,之前很多的教材都是用C语言实现链表,因为c有指针,可以很方便的控制内存,很方便就实现链表,其他的语言,则没那么方便,有很多都是用 ...

  3. java单向链表详解

    1.概述 单向链表(单链表)是链表的一种,其特点是链表的链接方向是单向的,对链表的访问要通过顺序读取从头部开始:链表是使用指针进行构造的列表:又称为结点列表,因为链表是由一个个结点组装起来的:其中每个 ...

  4. JavaScript数据结构与算法——链表详解(下)

    在JavaScript数据结构与算法--链表详解(上)中,我们探讨了一下链表的定义.实现原理以及单链表的实现.接下来我们进一步了解一下链表的其他内容. 1.双向链表 双向链表实现原理图: 与单向链表不 ...

  5. java数据结构-链表详解

    文章目录 1.数据结构-链表详解 1.1单链表 1.1.1单链表节点的尾部添加 1.1.2单链表节点的自动排序添加 1.1.3单链表节点的修改 1.1.4单链表节点的删除 1.2单链表面试题 1.2. ...

  6. JavaScript数据结构与算法——链表详解(上)

    注:与之前JavaScript数据结构与算法系列博客不同的是,从这篇开始,此系列博客采用es6语法编写,这样在学数据结构的同时还能对ECMAScript6有进一步的认识,如需先了解es6语法请浏览ht ...

  7. 数据结构--图(Graph)详解(四)

    数据结构–图(Graph)详解(四) 文章目录 数据结构--图(Graph)详解(四) 一.图中几个NB的算法 1.普里姆算法(Prim算法)求最小生成树 2.克鲁斯卡尔算法(Kruskal算法)求最 ...

  8. 数据结构--图(Graph)详解(一)

    数据结构–图(Graph)详解(一) 文章目录 数据结构--图(Graph)详解(一) 一.图的基本概念 1.图的分类 2.弧头和弧尾 3.入度和出度 4.(V1,V2) 和 < V1,V2 & ...

  9. C语言结构体与指针ppt,c语言指针和结构体:链表详解.ppt

    c语言指针和结构体:链表详解.ppt 1,第十一章 链表,2,例跳马.依下图将每一步跳马之后的位置x,y放到一个"结点"里,再用"链子穿起来",形成一条链,相邻 ...

  10. 数据结构与算法详解目录

    数据结构与算法详解是一本以实例和实践为主的图书,主要是经典的数据结构与常见算法案例,来自历年考研.软考等考题,有算法思路和完整的代码,最后提供了C语言调试技术的方法. 后续配套微课视频. 第0章  基 ...

最新文章

  1. 他24岁,4篇Nature在手,也会关心学不懂C语言怎么办
  2. 【整合篇】Activiti业务与流程的整合
  3. Android进阶:七、Retrofit2.0原理解析之最简流程【上】
  4. SSRS Report Knowledge Base
  5. SpringBoot+Vue+HIKVSION实现摄像头多选并多窗口预览(插件版)
  6. mysql bytessent_如何对DSQLSERVER、MySQL、Orache语句性能分析
  7. 微软中国推校园先锋计划,保障学生低价获取正版软件
  8. 部门日报系统部署备忘录
  9. 禁用select下拉方法
  10. 梅西、内马尔谁是全能的五边形战士?教你用BI做出可视化能力图
  11. java XML 通过BeanUtils的population为对象赋值 根据用户选择进行dom4j解析
  12. php多语言商城,Ecshop商城多国语言修改方法
  13. python快速入门豆瓣_python爬虫实践——零基础快速入门(二)爬取豆瓣电影
  14. OpenGLES2.0渲图步骤:绘几何图形、图片处理、离屏渲染(3)
  15. 多家机构宣布接入文心一言能力
  16. 通过Node.js解析stl文件
  17. 微信小程序猜数字小游戏
  18. 新 Nano(五)自己写个库,读 DHT11 / DHT22
  19. 遥感影像去背景 之 数据裁剪
  20. EOS的经济模型是什么?

热门文章

  1. C语言向MySQL插入数据
  2. 帆软报表导出excel为0字节问题
  3. java-net-php-python-ssm创意分享网站计算机毕业设计程序
  4. android H5手机端锁屏自动定位问题
  5. 天津事业编计算机类考什么,天津事业编考试考什么内容
  6. html 自动填充 颜色,周六周日行自动填充颜色
  7. nodejs与Promise的思想碰撞
  8. SSM框架下log4j配置说明
  9. 【微信小程序】 解决“enablePullDownRefresh“: true下拉刷新还是不起作用
  10. 用VLOOKUP函数在Excel中批量替换值