第2章线性表

合集下载

《数据结构与算法(C++语言版)》第2章 线性表

《数据结构与算法(C++语言版)》第2章 线性表
• 以下是一个使用类LinearList的C++程序,它假定之前的程 序均存储在LinearList.h之中,且异常类定义位于文件 exception.h之中。该示例完成以下操作:创建一个大小为5 的整数线性表L;输出该表的长度(为0);在第0个元素之 后插入2;在第一个元素之后插入6和8(至此,线性表为2, 6,8);寻找并输出第一个元素(为2);输出当前表的长 度(为3);删除并输出第一个元素。
数据结构与算法 (C++语言版)
第2章 线性表
线性表的类型定义
• 基本概念 • 线性表是由n(n≥0)个类型相同的数据元素组成的有限序 列,通常表示为L=(a1, …, ai–1, ai, ai+1, …, an)。其中,L为线 性表名称,ai为组成该线性表的数据元素,ai–1领先于ai,ai 领先于ai+1,称ai–1是ai的直接前驱元素,ai+1是ai的直接后继 元素。当i=1, 2, …, n–1时,ai有且仅有一个直接后继;当 i=2, 3, …, n时,ai有且仅有一个直接前驱。 • 线性表的长度就是线性表中元素的个数n(n≥0)。当n=0时, 称为空表。在非空表中的每个数据元素都有一个确定的位 置,如a1是第一个数据元素,an是最后一个数据元素,ai是 第i个数据元素。称i为数据元素ai在线性表中的位序。
线性表的类型定义
Prev_Elem(L, cur_e, &pre_e) //返回当前元素的前一个元素值 输入:线性表L。 输出:若cur_e是线性表L的数据元素,且不是第一个,则用 pre_e返回它的直接前驱元 素;否则操作失败,pre_e无定义。 Next_Elem(L, cur_e, &next_e) //返回当前元素的后一个元素值 输入:线性表L。 输出:若cur_e是线性表L的数据元素,且不是最后一个,则用 next_e返回它的直接后继元素;否则操作失败,next_e无定 义。

数据结构课件第2章线性表

数据结构课件第2章线性表

27
线性表的顺序存储结构适用于数据 元素不经常变动或只需在顺序存取设备 上做成批处理的场合。为了克服线性表 顺序存储结构的缺点,可采用线性表的 链式存储结构。
28
2.3 线性表的链式存储结构
线性表的链式存储表示 基本操作在单链表上的实现 循环链表 双向链表 线性表链式存储结构小结
2.3.1 线性表的链式存储表示 29
2.1.1 线性表的定义
6
一个线性表(linear_list)是 n(n≥0)个具有相同属性的数 据元素的有限序列,其中各元素有着依次相邻的逻辑关系。
线性表中数据元素的个数 n 称为线性表的长度。当 n = 0 时 该线性表称为空表。当 n > 0 时该线性表可以记为:
(a1,a2,a3,…,ai,…,an)
数据域 指针域
结点 data next
31
(2) 线性表的单链表存储结构
通过每个结点的指针域将线性表中 n 个结点按其逻辑顺序链 接在一起的结点序列称为链表,即为线性表 ( a1, a2, a3, …, ai, …, an ) 的链式存储结构。如果线性链表中的每个结点只有一个指针域, 则链表又称为线性链表或单链表 (linked list)。
17
(2) 算法编写
#define OK 1
#define ERROR 0
Int InsList ( SeqList *L, int i, ElemType e ) /*在顺序线性表 L 中第 i 个位置插入新的元素 e。*/ /* i 的合法值为 1≤i ≤L->last+2*/ {
int k; if ( i < 1) ||( i > L->last+2)) /*首先判断插入位置是否合法*/ { printf(“插入位置i值不合法”);

第二章线性表

第二章线性表

;查询通讯录信息。
第2页
目录
目录 退出
第二章 线性表
struct TelRed {char name[20]; char tel[12]; }; struct TelRed TelBook[100]; int length; 结构体数组TelBook和表示通讯录长度length二者实际 上是作为通讯录的一部分出现的,将二者作为一个整体来 表示通讯录。
第21页
目录
目录 退出
第二章 线性表
算法思想:
1)检查 i 值是否超出所允许的范围 (1 i n + 1) ,若超出
,则进行“超出范围”错误处理; 2)将线性表的第 i 个元素和它后面的所有元素均后移一个 位置; 3)将新元素写入到空出的第 i 个位置上;
4)使线性表的长度增 1。
第22页
第10页
目录
目录 退出
第二章 线性表
③ DestroyList(&L) 初始条件:线性表L已存在。
操作结果:销毁线性表L。
④ ClearList(&L) 初始条件:线性表L已存在。 操作结果:将L置为空表。 ⑤ EmptyList(L) 初始条件:线性表L已存在。 操作结果:如果L为空表,则返回TRUE,否则返回FALSE。 ⑥ GetData(L,i,&a) 初始条件:表L存在,且1≤i≤ListLength(L)。 操作结果:用a返回线性表L中第i个数据元素的值。
2、有且仅有一个终端结点 an,它没有直接后继,而仅有 一个直
接前趋 an -1, an 叫表尾元素;
3、其余的内部结点 ai (2 i n -1) 都有且仅有一个直接 前趋 ai –1
和一个直接后继 ai +1。

吉林大学数据结构_第二章 线性表

吉林大学数据结构_第二章 线性表

如何找指定位置的结点?
• 与顺序表不同,单链表无法直接访问指定 位置的结点,而是需要从哨位结点开始, 沿着next指针逐个结点计数,直至到达指定 位置。
操作
• • • • 存取 查找 删除 插入
存取算法
算法Find(k.item) /*将链表中第k个结点的字段值赋给item*/ F1. [k合法?] IF (k<1) THEN (PRINT “存取位置不合法”. RETURN.) F2. [初始化] p←head. i ←0. F3. [找第k个结点] WHILE (p ≠NULL AND i<k) DO (p←next(p). i ←i+1.) IF p=NULL THEN (PRINT “无此结点”. RETURN. ) item←data(p). ▍ 存取算法的时间复杂性分析。P30
插入算法
算法Insert(k,item) /*在链表中第k个结点后插入字段值为item的结点*/ I1.[k合法?] IF (k<0) THEN (PRINT “插入不合法”. RETURN) I2.[初始化] p←head. i ←0. I3.[p指向第k个结点] WHILE (p ≠NULL AND i<k) DO (p←next(p). i ←i+1.) IF p=NULL THEN (PRINT “插入不合法”. RETURN. ) I4.[插入] s<= AVAIL. data(s) ←item. next(s) ←next(p). next(p) ←s. ▍
删除算法
算法Delete(k.item) /*删除链表中第k个结点并将其字段值赋给item*/ D1.[k合法?] IF (k<1) THEN (PRINT “删除不合法”. RETURN.) D2.[初始化] p←head. i ←0. D3.[找第k-1结点] WHILE (p ≠NULL AND i<k-1) DO (p←next(p). i ←i+1.) IF p=NULL THEN (PRINT “无此结点”. RETURN. ) D4.[删除] q ← next(p). next(p) ← next(q) . item←data(q). AVAIL<=q.▍

《数据结构》课程课件第二章线性表

《数据结构》课程课件第二章线性表

Step2:数据域赋值
插入后: Step3:插入(连接)
X q
(1)式和(2)式的顺序颠倒,可以吗?
4、插入元素(在第i个元素之前插入元素e)
为什么时间复杂度不再是O(1)?
第i-1个元素
第i个元素
p
s
新插入元素
5、删除p所指元素的后继元素
P
删除前:
P->next P->next->next
删除:
五、线性表ADT的应用举例
Void mergelist(list La,list Lb,list &Lc)
{ //已知线性表La和Lb中的数据元素按值非递减排列
//归并La和Lb得到新的线性表Lc,Lc中的元素也按值非递减排列
例: 将两个各有n个元素的有序表归并成一个有序表, 其最小的比较次数是( )。 A、n B、2n-1 C、2n D、n-1
三、线性表的ADT
四、线性表的分类
五、线性表ADT的应用举例
例1:已知有线性表L,要求删除所有X的出现
五、线性表ADT的应用举例
例2: 已知有两个分别有序的线性表(从小到大),要 求合并两个线性表,且合并后仍然有序。——归并 方法1: 合并,再排序O((m+n)2)
方法2: 归并,利用分别有序的特点O((m+n))
二、线性表上常见的运算
8、删除 Delete(L,i):删除线性表的第i个元素 删除前 a1 a2 … ai-1 ai ai+1 … an 删除后 a1 a2 … ai-1 ai+1 … an 9、判断是否为空 Empty(L):线性表空,则返回TRUE, 否则FALSE 10、输出线性表 Print(L):输出线性表的各个元素 11、其它操作 复制、分解、合并、分类等

《数据结构C语言版》----第02章

《数据结构C语言版》----第02章

同理可证:顺序表删除一元素的时间效率为: 同理可证:顺序表删除一元素的时间效率为: T(n)=(n-1)/2 ≈O(n) O(n) (
插入效 E = ∑ is 率: i=0
n
1 n n pi ( n − i ) = ∑ (n − i) = 2 n + 1 i=0
n −1 删除效 1 n −1 n −1 Edl = ∑ qi (n − i ) = ∑ (n − i ) = 率: n i =0 2 i =0
2.2 线性表的顺序表示和实现
顺序存储结构的线性表称作顺序表 1.顺序表的存储结构 顺序表的存储结构
实现顺序存储结构的方法是使用数组。数组把线性表 实现顺序存储结构的方法是使用数组。 使用数组 的数据元素存储在一块连续地址空间的内存单元中, 连续地址空间的内存单元中 的数据元素存储在一块连续地址空间的内存单元中,这样 线性表中逻辑上相邻的数据元素在物理存储地址上也相邻。 线性表中逻辑上相邻的数据元素在物理存储地址上也相邻。 数据元素间的逻辑上的前驱、 数据元素间的逻辑上的前驱、后继逻辑关系就表现在数据 元素的存储单元的物理前后位置上。 元素的存储单元的物理前后位置上。 顺序表的存储结构如图所示
2.线性表抽象数据类型 2.线性表抽象数据类型
数据集合:{ 的数据类型为DataType 数据集合 { a0, a1, … , an-1 }, ai的数据类型为 (1) ListInitiate(L) 初始化线性表 (2) ListLength(L) 求当前数据元素个数 操作集合: 操作集合 (3) ListInsert(L,i,x) 插入数据元素 (4) ListDelete(L,i,x) 删除数据元素 (5) ListGet(L,i,x) 取数据元素
printf("参数 不合法 \n"); 参数i不合法 参数 不合法! return 0;

线性表ppt

线性表ppt
由于C语言函数的参数仅能向被调函数传值,这个值在返 回时也不会改变,因此在上面的算法中,采用指针变量v做形 参,虽然从被调函数返回时指针v值不变,但是v地址中所代表 的结构体的内容发生了变化。这就是所谓的传址调用。
假设在主函数中已经建立了线性表结构体s,并且要在第3 个位置插入88,语句如下:
insert ( &s,3,88);
其他特 VIP专享精彩活动

VIP专属身份标识
开通VIP后可以享受不定期的VIP随时随地彰显尊贵身份。
专属客服
VIP专属客服,第一时间解决你的问题。专属客服Q全部权益:1.海量精选书免费读2.热门好书抢先看3.独家精品资源4.VIP专属身份标识5.全站去广告6.名
以用来说明结构体变量:
Sqlist1 a; 在正式使用a之前必须为数据成员elem分配足够的空间。 语句如下:
a.elem=(Sqlist1 *)malloc(MAXSIZE*sizeof(Sqlist1)); 对结构体内elem子域的访问与前文有所不同。在输入/输出时 的情况,也与前文有所不同。在程序运行结束之前,这些动态 分配的存储空间还要释放归还给系统,语句如下:
(5) Insert(L,i,x) 在线性表中第i个元素之后(或之前)插入一个新元素x;
(6) Delete(L,i) 删除线性表中的第i个元素;
(7) Empty(L)
判断线性表是否为空;
(8) Clear(L)
将已知的线性表清理为空表;
第2章 线 性 表
在上述的操作运算中,最基本最重要的是插入、删除。 线性表的其他复杂操作和运算还有:对有序表的插入和删除; 按某种要求重排线性表中各元素的顺序;按某个特定值查找 线性表中的元素;两个线性表的合并等。

第2章 线性表

第2章 线性表

【例2】巳知有两个按元素值递增有序的顺序表La和 Lb,设计一个算法将表La和表Lb的全部元素归并 为一个按元素值递增有序的顺序表Lc。

算法思路:用i扫描顺序表La,用j扫描顺序表Lb。 当表La和表Lb都未扫描完时,比较两者的当前元 素,将较小者插入表Lc的表尾,若两者的当前元 素相等,则将这两个元素依次插入表Lc的表尾。 最后,将尚为扫描完的顺序表的余下部分元素依 次插入表Lc的表尾。算法如下: void MergeList_Sq(SqList La, SqList Lb, SqList &Lc)

表中ai-1领先于ai,称ai-1是ai的直接前驱,ai+1是 ai的直接后继。

线性表的抽象数据类型定义 (参见教材)
返回本章目录
2.2 线性表的顺序存储结构

线性表的顺序存储是指在内存中用地址连续的一块存储空间 依次存放线性表的数据元素,用这种存储形式存储的线性表 称其为顺序表。 假设每个数据元素占d个存储单元,且将ai的存储地址表示为 Loc(ai),则有如下关系: Loc(ai)=Loc(a1)+(i-1)*d Loc(a1)是线性表的第一个数据元素a1的存储地址,通常 称作线性表的基地址。

【例1】 编写一算法,从顺序表中删除自第i个元素开 始的k个元素。 算法思路: 为保持顺序表的逻辑特性,需将i+k ~ n位 置的所有元素依次前移k个位置。算法如下:

int deleteK(Sqlist &sq,int i,int k)
{ if (i<1||k<1||i+k-1>sq.len) return 0; for (j=i+k-1;j<=sq.len-1;j++) sq.data[j-k]=sq.data[j]; sq.len-=k; return 1; }// deleteK
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
第2章 线性表
线性结构特点
在数据元素的非空有限集中
– 存在唯一的一个被称作“第一个”的数据元素 – 存在唯一的一个被称作“最后一个”的数据元 素 – 除第一个外,集合中的每个数据元素均只有一 个前趋 – 除最后一个外,集合中的每个数据元素均只有 一个后继
本章学习目标
• • • • 线性表的数据结构、特点 线性表的两种主要的存储结构 顺序存储结构下基本运算的实现 链式存储结构的优缺点、基本运算的实现
n
顺序表的删除
• 算法分析:第n-1 (因为下标从0开始)个 元素到第i+1个元素向前平移,直接删除第 i个数据元素。 • 注意:对数据元素进行平移时,应该从前 向后移动,不应该反向移动。同时应该判 断i的取值是否合理。
顺序表的删除
• 算法的实现:P27 • 时间复杂度分析:该算法主要的时间花费在 for循环上(即数据元素的移动次数上),最 好的情况下移动次数是0(i=n),最坏的情 况下移动次数是n-1(i=1),整个循环的次数为 n-i,所以时间不仅与规模长度有关,而且与删 除的位臵有关。其时间复杂度为 O(n)。
故在顺序表中插入或删除一个元素时,平均移 动表的大约一半元素,当n很大时,效率很低
• 顺序表的“求表长”和取第i个数据元素的 时间复杂度均为O(1),因为可以直接求出 线性表的长度, 顺序存储下可以实现随机 存取,可以直接取得数据元素,而不需要 移动元素。
– 顺序存储结构的优缺点
• 优点 – 逻辑相邻,物理相邻 – 可随机存取任一元素 – 存储空间使用紧凑 • 缺点 – 插入、删除操作需要移动大量的元素 – 预先分配空间需按最大空间分配,利用不充分 – 表容量难以扩充
2.2 线性表的顺序表示和实现
• 线性表的存储结构分为顺序存储和非顺序存 储。其中顺序存储也称为向量存储或一维数 组存储。 • (1)顺序表 – 线性表的顺序存储,也称为向量存储,又 可以说是一维数组存储。线性表中结点存 放的物理顺序与逻辑顺序完全一致,它叫 向量存储(一般指一维数组存储)。
2.2 线性表的顺序表示和实现
顺序表的插入
• 插入:在线性表的第i-1个数据元素和第i个 数据元素之间插入一个新的数据元素,使 线性表的长度增加一个元素的空间。
数组下标 0 1
内存 元素序号
a1 a2 1 2
数组下标 0 1
内存 元素序号
a1 a2 1 2
i-1 i
ai ai+1
i i+1
i-1 i
x
ai ai+1
i i+1
2.3 线性表的链式存储结构
• 2.3.1 单向链表
– 任意存储单元存储线性表的数据元素,对于链式存储线 性表时,其特点形式如图所示:
DATA
NEXT
•其中data 是数据域,存放数据元素的值;next是指针 域,存放相邻的下一个结点的地址,单向链表是指结 点中的指针域只有一个的沿着同一个方向表示的链式 存储结构。 •因为结点是一个独立的对象,所以在JAVA中能够实现 独立的结点类。
n-1 n
an
n n+1
n-1 n
an-1 an
n
n+1
顺序表的插入
• 算法分析:第i个元素到第n-1(因为下标 从0开始)个元素向后平移,空出一个存储 单元后,插入该元素。 • 注意:对数据元素进行平移时,应该从后 向前移动,不应该反向移动(思考:如果 反向移动,会出现什么样的结果?)。同 时应该判断i的取值是否合理。另还要考虑 当前的数据个数是否为0。
顺序表的删除
• 删除:删除线性表的第i个数据元素,使线 性表的长度减少一个元素的空间。
数组下ห้องสมุดไป่ตู้ 0 1
内存 元素序号
a1 a2 1 2
数组下标 0 1
内存 元素序号
a1 a2 1 2
i-1 i
ai ai+1
i i+1
i-1 i
ai+1
ai+2
i i+1
n-1 n
an
n n+1
n-2 n-1
an
n-1
– 对线性表的所有数据元素,假设已知第一个数据元素 a1的地址为d1,每个结点占有c个存储单元, 则第i个 数据元素ai的地址为: – di=d1+(i-1)*c – 线性表的第一个数据元素的位臵通常称做起始位臵或 基地址。 – 线性表的这种机内表示称做线性表的顺序存储结构或 顺序映象(Sequential mapping),使用这种存储结 构存储的线性表又称做顺序表。其特点是,表中相邻 的元素之间具有相邻的存储位臵。 – 在使用一维数组时,数组的下标起始位臵根据给定的 问题确定,或者根据实际的高级语言的规定确定。
2.1 线性表类型的定义
• 线性表是n个数据元素的有限序列。其一般描述 为: • A=(a1,a2,……an) • 其中A称为线性表的名称, 每个ai(n≥i≥1)称为 线性表的数据元素,具体n的值含义则称为线性 表中包含有数据元素的个数,也称为线性表的长 度;当n的值等于0时,表示该线性表是空表。每 个数据元素的含义在不同情况下各不相同,它们 可能是一个字母、一个数字、也可以是一条记录 等。一般情况下,在线性表中每个ai的描述的是 一组相同属性的数据。
插入算法时间复杂度分析
• 设Pi是在第i个元素之前插入一个元素的概率,则 在长度为n的线性表中插入一个元素时,所需移动 的元素次数的平均次数为:
Eis Pi (n i 1)
1 若认为P i n 1 n n 1 则Eis ( n i 1) n i 1 2
i 1
2.3 线性表的链式存储结构
• 线性表的顺序存储结构的特点是逻辑关系上相邻 的两个元素在物理位臵上也相邻,因此随机存取 元素时比较简单,但是这个特点也使得在插入和 删除元素时,造成大量的数据元素移动,同时如 果使用静态分配存储单元,还要预先占用连续的 存储空间,可能造成空间的浪费或空间的溢出。 • 如果采用链式存储,就不要求逻辑上相邻的数据 元素在物理位臵上也相邻,因此它没有顺序存储 结构所具有的弱点,但同时也失去了可随机存取 的优点。
2.2 线性表的顺序表示和实现
• (1)顺序表
– 顺序分配的线性表的可以直接使用一维数组描述为: – type arraylist[];//type的类型根据实际需要确定// – 通常用在数组的元素个数不是很多且可以对数组元素“枚 举”的情况下。也可以使用符合类型数组的动态进行动态 定义。 – type arrayname[]; – 该代码只是对应用数组的声明,还没有对该数组分配空间, 因此不能访问数组。只有对数组进行初始化并申请内存资 源后,才能够对数组中元素进行使用和访问。 – arrayname= new type[arraysize]; – 其作用是给名称为arrayname的数组分配arraysize个类型 为type大小的空间;其中arraysize表示数组的长度,它可 以是整型的常量和变量;如果arraysize是常量,则分配固 定大小的空间,如果是变量,则表示根据参数动态分配数 组的空间。
2.1 线性表类型的定义
• 使用抽象数据类型ADT定义线性表如下: • ADT list{ • 数据对象:D={ai | ai∈元素集合,i=1, 2,……n,n≥0} • 数据关系:R= {〈ai-1,ai〉 | ai-1,ai∈元素集 合,i=1,2,……n} • 基本操作: • {将P23~24对线性表的操作搬过来,每个函数注 明输入输出} • }ADT list
2.2 线性表的顺序表示和实现
• • • • • 如: int array[]=new int[10]; int array[]; array=new int[10]; int array[]={1,2,3,4,5};
2.2 线性表的顺序表示和实现
(2)顺序表基本运算的实现 • 线性表的顺序存储的结构,容易实现线性 表的某些操作,如随机存取第i个数据元素 等,但是在插入或删除数据元素时则是比 较烦琐,所以顺序存储结构比较适合存取 数据元素。应该注意java的数组下标从0开 始。下面考虑线性表顺序存储的插入、删 除的实现方法。
n
T n On
删除算法时间复杂度分析
• 设Qi是删除第i个元素的概率,则在长度为n的线性表中删 除一个元素时,所需移动的元素次数的平均次数为:
Ede Qi (n i )
i 1
n
T n O n
1 若认为Qi n 1 n n 1 则E de (n i ) 2 n i 1
例 英文字母表(A,B,C,…..Z)是一个线性表

学号 001 002 ……
姓名 张三 李四 ……
年龄 18 19 ……
数据元素
– 特征:
• 元素个数n—表长度,n=0空表 • 1<i<n时
– ai的直接前趋是ai-1,a1无直接前驱 – ai的直接后继是ai+1,an无直接后继
• 元素同构,且不能出现缺项
结点类的构造--例一
• • • • • • • • • • • • • • • • • • • 例一://////////////////////////////////////////////////////////////// class Link { public int iData; // data item public double dData; // data item public Link next; // next link in list // ------------------------------------------------------------public Link(int id, double dd) // constructor { iData = id; // initialize data dData = dd; // ('next' is automatically } // set to null) // ------------------------------------------------------------public void displayLink() // display ourself { System.out.print("{" + iData + ", " + dData + "} "); } } // end class Link ////////////////////////////////////////////////////////////////
相关文档
最新文档