【数据结构】线性表的链式存储-单链表
单链表的定义
线性表的链式存储又称为单链表,它是指通过一组任意的存储单元来存储线性表中的数据元素。 为了建立起数据元素之间的线性关系,对每个链表结点,除了存放元素自身的信息之外,还需要存放一个指向其后继的指针。
每个结点包括数据域和指针域。节点是一个结构体,看一下结构体的定义:
typedef struct LNode{ElemType data;struct LNode *next;
}LNode,*LinkList;
注意这是节点而不是整个单链表。
节点的第一个部分是数据域data。
第二个部分是指针next,指向的类型是节点的类型,表示指向下一个节点。
节点的名字取为LNode。
结构体的指针类型记作LinkList。
那么如何表示一个单链表呢?
单链表的两种建表方法
头结点和头指针的区别?
不管带不带头结点,头指针始终指向链表的第一个结点,而头结点是带头结点链表中的第一个结点,结点内通常不存储信息。
为什么要设置头结点?
- 处理操作起来方便 例如:对在第一元素结点前插入结点和删除第一结点起操作与其它结点的操作就统一了
- 无论链表是否为空,其头指针是指向头结点的非空指针,因此空表和非空表的处理也就统一了。
如何建立单链表?按照插入位置分为两种方式:
1.头插法建立单链表:
建立新的节点分配内存空间,将新节点插入到当前链表的表头
LinkList CreatList1(LinkList &L)
{LNode *s; //辅助指针int x; //储存插入节点的数据的值L=(LinkList)malloc(sizeof(LNode));//创建头节点L->next=NULL; //初始为空链表scanf("%d",&x); //输入节点的值while(x!=9999){ //输入9999表示结束(要根据实际题目来确定终止条件)s=(LNode*)malloc(sizeof(LNode)); //创建新节点s->data=x; //对新节点的数据域进行赋值s->next=L->next; //**新节点的后继指向第一个节点**L->next=s; //**头节点的后继指向新节点**scanf("%d",&x); //读入下一个节点值}return L; //返回建好的链表的头指针L
}
头插法建立单链表,读入数据的顺序与生成的链表中元素的顺序是相反的。
2.尾插法建立单链表
建立新的结点分配内存空间,将新结点插入到当前链表的表尾。
需要增加一个指向表尾元素的尾指针。
LinkList CreatList2(LinkList &L)
{int x;L=(LinkList)malloc(sizeof(LNode)); //带头节点的链表LNode *s,*r=L; //r为表尾指针 指向表尾scanf("%d",&x); //输入结点的值while(x!=9999){ //输入9999表示结束s=(LNode*)malloc(sizeof(LNode));s->data=x;r->next=s;r=s; //r指向新的表尾结点scanf("%d",&x);}r->next=NULL; //尾结点指针置空return L;
}
尾插法建立单链表,读入数据的顺序与生成的链表中元素L 的顺序是相同的。
单链表的基本操作
按序号查找
在单链表中从第一个结点出发,顺指针next域逐个往下搜索,直到找到第i个结点为止,否则返回最后一个结点指针域NULL。
因为是查找结点,所以函数的返回类型是指向结点的指针类型。
参数有两个,是链表L和结点序号i(只需对链表进行读取,不需修改,所以不必设置引用类型)
LNode *GetElem(LinkList L,int i)
{int j=1; //计数,初始为1LNode *p=L->next; //第一个结点指针赋给pif(i==0) //若i等于0,则返回头结点return L; if(i<1) //若i无效,则返回NULLreturn NULL;while(p&&j<i) //从第1个结点开始找,查找第i个结点 (此处一定要判断p不为空){p=p->next;j++;}return p; //返回第i个结点的指针,如果i大于表长,直接返回p即可
}
按值查找
从单链表第一个结点开始,由前往后依次比较表中各结点数据域的值,若某结点数据域的值等于给定值e,则返回该结点的指针;若整个单链表中没有这样的结点,则返回NULL。
LNode *LocateElem(LinkList L,ElemType e)
{LNode *p=L->next;while(p!=NULL&&p->data!=e) //从第1个结点开始查找data域为e的结点(此处一定要判断p不为空)p=p->next;return p; //找到后返回该结点指针,否则返回NULL
}
插入
插入操作是将值为x的新结点插入到单链表的第i个位置上。先检查插入位置的合法性,然后找到待插入位置的前驱结点,即第i−1个结点,再在其后插入新结点。
算法思路:
- 取指向插入位置的前驱结点的指针
① p=GetElem(L,i-1); - 令新结点s的指针域指向p的后继结点
② s->next=p->next; - 令结点p的指针域指向新插入的结点s
③ p->next=s;
bool ListFrontInsert(LinkList L,int i,ElemType e)
{LinkList p=GetElem(L,i-1);if(NULL==p){return false;}LinkList s=(LNode*)malloc(sizeof(LNode));//为新插入的结点申请空间s->data=e;s->next=p->next;p->next=s;return true;
}
删除
删除操作是将单链表的第i个结点删除。先检查删除位置的合法性,然后查找表中第i−1个结点,即被删结点的前驱结点,再将其删除。
算法思路:
- 取指向删除位置的前驱结点的指针 p=GetElem(L,i-1);
- 取指向删除位置的指针 q=p->next;
- p指向结点的后继指向被删除结点的后继 p->next=q->next
- 释放删除结点 free(q);
bool ListDelete(LinkList L,int i)
{LinkList p=GetElem(L,i-1);if(NULL==p){return false;}LinkList q;q=p->next;p->next=q->next;free(q);return true;
}
参考资料
https://www.bilibili.com/video/av36895433/?p=11
【数据结构】线性表的链式存储-单链表相关推荐
- 线性表的链式存储-单链表
单链表操作 [x] 单链表的创建(尾插法.头插法) [x] 单链表的查找操作 [x] 单链表的删除操作 [x] 单链表的逆置操作(使用头插法) [x] 单链表表长的计算 [x] 打印单链表 单链表的创 ...
- 数据结构-线性表(链式存储结构)
线性表(链式存储结构) 特点: 用一组任意的存储单元存储线性表的数据结构,这组存储单元可以是连续的,也可以是不连续的. 对数据结构ai来说,除了存储其本身的信息之外,还需存储一个指示其后继的信息(即直 ...
- JAVA数据结构 线性表的链式存储及其实现
2019独角兽企业重金招聘Python工程师标准>>> 2线性表的链式存储及其实现 虽然顺序表具有随机存取的特点是一种有用的存储结构但是也有缺陷: (1) 若需要给顺序表增 ...
- 数据结构-线性表的链式存储(包含代码实现)
线性表的链式表示和实现 链式存储结构 结点在存储器中的位置是任意的,即逻辑上相邻的数据元素在物理上不一定相邻 线性表的链式存储结构又称为非顺序映像或链式映像. 用一组物理位置任意的存储单元来存放线性表 ...
- 线性表的链式表示——单链表
单链表 定义 线性表的链式存储又称单链表,它是指通过一组任意的存储单元来存储线性表中的数据元素.每个链表的结点,除存放元素自身的信息之外,还需要存放一个指向其后继结点的指针.即单链表的结构分为两部分, ...
- 线性表的链式实现(单链表)
单链表的定义 为了表示每个数据元素与其直接后续元素之间的逻辑关系,每个元素除了存储本身的信息外,还需要存储指示其直接后续的信息,即每个结点存放本身的数据元素和下一个元素的地址.n个结点连接成一个链式线 ...
- 用Java描述数据结构之线性表的链式存储(链表),模拟LinkedList实现
上一篇介绍了顺序表:用Java描述数据结构之线性表的顺序存储(顺序表),ArrayList及其方法的介绍 上一篇博客中说明了什么是线性表--线性表就是一个个数据元素逻辑上以一对一的相邻关系(但是在物理 ...
- 【数据结构】线性表的链式存储-双链表
引言 单链表结点中只有一个指向其后继的指针,这使得单链表只能从头结点依次顺序地向后遍历.若要访问某个结点的前驱结点(插入.删除操作时),只能从头开始遍历 ,访问后继结点的时间复杂度为 0(1),访问前 ...
- 数据结构(四) -- C语言版 -- 线性表的链式存储 - 循环链表
文章目录 零.读前说明 一.循环链表的概述 二.循环链表的模型 2.1.包含头节点模型 2.2.不包含头节点模型 三.工程结构及简单测试案例 3.1.测试工程的目录结构 3.2.循环链表示例源码 3. ...
最新文章
- 理解在javascript中的内存泄露
- 详解MySQL查询缓存
- opeansea, nft, trend
- latex的资料ftp
- 快速配置 Samba
- Linux 进程号 端口号 互找
- html通用的排班方法,呼叫中心排班的两种主要方法
- 从零开发区块链应用(一)--golang配置文件管理工具viper
- NOIP2016 游记
- glide 压缩图拍呢_Glide-图片的压缩
- Grafana panel 图形高级定制
- excel怎么合并同类项数据并求和(去除重复项)
- 4.8 putsgets函数
- 电子凸轮应用追剪算法详细图解(附PLC完整源代码)
- ADSP-21489的图形化编程详解(6:一段 EQ,24 段 EQ,31段EQ)
- 教外谈(3):C/C++实现本地搜索引擎
- [DP] UOJ #311. 【UNR #2】积劳成疾
- matlab 路由表,闭关修炼之zigbee路由
- 拍手数据集_我如何(重新)建立中等拍手效果-以及从实验中得到的结果。
- [心得]google软件工程师技术准备