数据结构线性表PPT
合集下载
数据结构第二章线性表.ppt
构造原理
用一组地址连续的存储单元依次存储线性表的数据元素,数 据元素之间的逻辑关系通过数据元素的存储位置直接反映。
k个单元 (a1,a2,a3,... ...,an)
a1 a2 a3
……
an
LOC(ai)
d1+k=d2 d3
………
dn
所谓一个元素的地址是指该元素占用的
若干(连续的)存储单元的第一个单元的地址。
LOC(a5)=100+(5-1)*4=116
线性表 11
顺序存储结构示意图
(a1,a2,a3,... ...,an)
当前已经占用的空间
尚未使用的空间
a1 a2 a3 … … an-1 an
01 2
n-2 n-1 n
……
n+1
M-1
事先分配给线性表的空间
线性表 12
一般来说,长度为n的线性表(a1,a2,…,an)在计算机中 的结构如下:
INSERT(L,x,i)。 6.删除线性表中第i个数据元素DELETE(L,i)。 7.对线性表中的数据元素进行升序或者降序排序。 8.将两个或两个以上的线性表合并成为一个线性表。 9.将一个线性表分解为两个或两个以上的线性表路】 依次输出线性表中的每个元素的值。
编写在线性表A中删除线性表B中出现的元素的算法。
1 3 57 9
12346
579
【算法思路】 依次检查线性表B中的每个元素,看它是否在线性表
A中。若在A中,则将其从A中删除。
线性表
5
void delete(Sqlist *A,Sqlist *B) {
int i,k;
datatype x;
for(i=1;i<=LENGTH(B);i++) {
用一组地址连续的存储单元依次存储线性表的数据元素,数 据元素之间的逻辑关系通过数据元素的存储位置直接反映。
k个单元 (a1,a2,a3,... ...,an)
a1 a2 a3
……
an
LOC(ai)
d1+k=d2 d3
………
dn
所谓一个元素的地址是指该元素占用的
若干(连续的)存储单元的第一个单元的地址。
LOC(a5)=100+(5-1)*4=116
线性表 11
顺序存储结构示意图
(a1,a2,a3,... ...,an)
当前已经占用的空间
尚未使用的空间
a1 a2 a3 … … an-1 an
01 2
n-2 n-1 n
……
n+1
M-1
事先分配给线性表的空间
线性表 12
一般来说,长度为n的线性表(a1,a2,…,an)在计算机中 的结构如下:
INSERT(L,x,i)。 6.删除线性表中第i个数据元素DELETE(L,i)。 7.对线性表中的数据元素进行升序或者降序排序。 8.将两个或两个以上的线性表合并成为一个线性表。 9.将一个线性表分解为两个或两个以上的线性表路】 依次输出线性表中的每个元素的值。
编写在线性表A中删除线性表B中出现的元素的算法。
1 3 57 9
12346
579
【算法思路】 依次检查线性表B中的每个元素,看它是否在线性表
A中。若在A中,则将其从A中删除。
线性表
5
void delete(Sqlist *A,Sqlist *B) {
int i,k;
datatype x;
for(i=1;i<=LENGTH(B);i++) {
第2章--线性表PPT课件
一个(尾)结点。
.
4
a1,a2,…ai-1都是ai(2≦i≦n)的前驱,其中ai-1是ai的直接 前驱; ai+1,ai+2,…an都是ai(1≦i ≦n-1)的后继,其中ai+1是ai的 直接后继。
2.1.2 线性表的逻辑结构
线性表中的数据元素ai所代表的具体含义随具体应 用的不同而不同,在线性表的定义中,只不过是一个抽 象的表示符号。
以下将对几种主要的操作进行讨论。
1 顺序线性表初始化
Status Init_SqList( SqList *L )
{ L->elem_array=( ElemType * )malloc(MAX_SIZE*sizeof( ElemType ) ) ;
if ( !L -> elem_array ) return ERROR ;
ListInsert ( L, i, &e )
初始条件:线性表L已存在,1≦i≦ListLength(L) ;
操作结果:在线性表L中的第i个位置插入元素e;
…
.
8
} ADT List
2.2 线性表的顺序存储
2.2.1 线性表的顺序存储结构
顺序存储 :把线性表的结点按逻辑顺序依次存放在 一组地址连续的存储单元里。用这种方法存储的线性表 简称顺序表。
在具体的机器环境下:设线性表的每个元素需占用L 个存储单元,以所占的第一个单元的存储地址作为数据元素 的存储位置。则线性表中第i+1个数据元素的存储位置 LOC(ai+1)和第i个数据元素的存储位置LOC(ai)之间满足 下列关系:
LOC(ai+1)=LOC(ai)+L
线性表的第i个数据元素ai的存储位置为:
数据结构线性表ppt课件
01
02
03
04
插入操作
在链表的指定位置插入一个新 节点,需要修改相邻节点的指
针。
删除操作
删除链表的指定节点,需要修 改相邻节点的指针。
查找操作
从链表的头节点开始,顺序遍 历链表,直到找到目标元素或
遍历到链表末尾。
遍历操作
从链表的头节点开始,顺序访 问每个节点,直到遍历到链表
末尾。
04 线性表应用举例 与问题分析
多项式表示与计算问题
01
02
03
多项式表示方法
数组表示法和链表表示法 。
数组表示法
将多项式的系数按次序存 放在一个数组中,通过下 标表示对应的幂次。
链表表示法
每个节点包含系数和指数 两个数据域,以及一个指 向下一个节点的指针域。
一元多项式相加算法设计
• 算法思想:将两个多项式中的同类项系数相加,得到新的 多项式。
删除操作
删除指定位置i的元素,需要将i之后的元素都向前移动 一个位置。
03 链式存储结构及 其实现
链式存储结构原理及特点
链式存储结构原理
使用一组任意的存储单元存储线 性表的数据元素(这组存储单元 可以是连续的,也可以是不连续 的)。
链式存储结构特点
逻辑上相邻的元素在物理位置上 不一定相邻,元素之间的逻辑关 系是通过指针链接来表示的。
...,an组成的有序序列。
性质
集合中必存在唯一的一个“第一元素 ”。
集合中必存在唯一的一个“最后元素 ”。
除最后元素之外,均有唯一的后继。
除第一元素之外,均有唯一的前驱。
线性表与数组关系
数组是线性表的一种表现和实现形式。
线性表更侧重于逻辑概念,而数组则是这种逻辑概念在计算机中的一种存储方式。
数据结构 线性表讲解ppt
③ 将该位置后的元素依次向前移动一个位置;
④ 修改当前表的长度;
17
2.2 线性表的顺序表示和实现--顺序表
/*在顺序表中删除第i个元素*/ int ListDelete_sq(SqList &L,int i,ElemType &e){ int k; /*删除位置不合法*/
if(i<1||i>L.length) return ERROR;
a1 a2 a3
……
ai-1
ai L.length L.listsize
10
2.2 线性表的顺序表示和实现--顺序表
3 顺序表的基本操作
顺序表的初始化
为顺序表分配一个预定义大小的一段连续单元, 并将其初始长度设为0。
int InitList_sq(SqList &L) { L.elem=(ElemType *)malloc( LIST_INIT_SIZE*sizeof(ElemType)); if(!L.elem) return ERROR; //初始化失败 L.length=0; //置空表长度为0 L.listsize=LIST_INIT_SIZE; //置初始空间容量 return OK; // 初始化成功,返回1 } //InitList_sq
采用一组任意的存储单元来存放线性表中的数据元 素,这些存储单元可以是连续的,也可以是不连续的。 数据元素间的逻辑关系通过附加信息-指针来描述。 数据元素除了具有代表其本身信息的数据域外,还 有一个用来指示逻辑关系的指针域。这两部分信息组成 数据元素的存储映像,称为结点。
数据域 data 指针域 next
}
O(La_len×Lb_len)
5
2.2 线性表的顺序表示和实现--顺序表
数据结构线性表ppt课件
➢ 数组(Array)存储具有相同数据类型的元素集合。 一维数组占用一块内存空间,每个存储单元的地 址是连续的,计算第i个元素地址所需时间复杂度 是一个常量, 与元素序号i无关。
线性表的分类
线性表 ADT
顺序存储结构 (元素连续存储、
继承
顺序表类
排序顺序表类
随机存取结构)
继承
链式存储结构
(元素分散存储)
单链表 双链表
单链表类 循环单链表 双链表 循环双链表类
排序单链表类
继承 排序循环双链表类
线性表的存储结构
2.2 线性表的顺序存储和实现
线性表的顺序存储结构
数组 :是实现顺序存储结构的基础。
数据结构
第 2 章 线性表
线性结构
线性结构是最常用、最简单的一种数据结构。而线性 表是一种典型的线性结构。其基本特点是线性表中的数据 元素是有序且是有限的。
线性结构基本特征: ① 存在一个唯一的被称为“第一个”的数据元素; ② 存在一个唯一的被称为“最后一个”的数据元素; ③ 除第一个元素外,每个元素均有唯一一个直接前驱; ④ 除最后一个元素外,每个元素均有唯一一个直接后 继。
其中LinearList称为线性表的名称 每个ai(n-1≥i≥0)称为线性表的数据元素,可以是整数、
浮点数、字符或类 表中相邻元素之间存在着顺序关系:将 ai-1 称为 ai 的前
驱(Predecessor),ai+1 称为 ai 的后继 (Successor)。a0没有前驱元素,an-1没有后继元素 具体n的值称为线性表中包含有数据元素的个数,也称 为线性表的长度(Length) 当n的值等于0时,表示该线性表是空表
2.1 线性表抽象数据类型
线性表的定义
线性表的分类
线性表 ADT
顺序存储结构 (元素连续存储、
继承
顺序表类
排序顺序表类
随机存取结构)
继承
链式存储结构
(元素分散存储)
单链表 双链表
单链表类 循环单链表 双链表 循环双链表类
排序单链表类
继承 排序循环双链表类
线性表的存储结构
2.2 线性表的顺序存储和实现
线性表的顺序存储结构
数组 :是实现顺序存储结构的基础。
数据结构
第 2 章 线性表
线性结构
线性结构是最常用、最简单的一种数据结构。而线性 表是一种典型的线性结构。其基本特点是线性表中的数据 元素是有序且是有限的。
线性结构基本特征: ① 存在一个唯一的被称为“第一个”的数据元素; ② 存在一个唯一的被称为“最后一个”的数据元素; ③ 除第一个元素外,每个元素均有唯一一个直接前驱; ④ 除最后一个元素外,每个元素均有唯一一个直接后 继。
其中LinearList称为线性表的名称 每个ai(n-1≥i≥0)称为线性表的数据元素,可以是整数、
浮点数、字符或类 表中相邻元素之间存在着顺序关系:将 ai-1 称为 ai 的前
驱(Predecessor),ai+1 称为 ai 的后继 (Successor)。a0没有前驱元素,an-1没有后继元素 具体n的值称为线性表中包含有数据元素的个数,也称 为线性表的长度(Length) 当n的值等于0时,表示该线性表是空表
2.1 线性表抽象数据类型
线性表的定义
数据结构(线性表)总结课件-2024鲜版
链表的查找
从头结点开始遍历链表,比较每个结点的 数据域与查找值,直到找到目标结点或遍 历完整个链表。
链表的遍历
从头结点开始,顺着指针依次访问每个结 点,直到尾结点。
链表的删除
删除指定位置的结点,需要修改相邻结点 的指针链接关系,并释放被删除结点的存 储空间。 2024/3/28
链表的插入
在指定位置插入一个新结点,需要修改相 邻结点的指针链接关系。
使用线性表来存储学生成绩信息,每个元素代表一个学生的成绩记录,
包含学号、姓名、各科成绩等属性。可以方便地进行学生成绩的录入、
查询、排序等操作。
20
05
线性表性能评价与改进策略
2024/3/28
21
时间复杂度分析
插入操作
在已知位置插入一个元素,需要移动插入位置 及之后的元素,时间复杂度为O(n)。
2
链表由一系列结点(每一个结点包含数据域和指 针域)组成,结点可以在运行时动态生成。
3
链表的特点是插入和删除操作灵活,不需要移动 大量元素,但查找操作相对较慢,需要从头结点 开始遍历。
2024/3/28
14
单链表、双向链表和循环链表
01
02
03
单链表
每个结点只包含一个指向 后继结点的指针,从头结 点开始,顺着指针可以遍 历整个链表。
02
数组的大小在创建时就已经确定,无法动态扩展。
不利于数据的动态变化
03
对于经常进行插入和删除操作的数据,使用数组作为存储结构
可能不是最优选择。
12
03
链式存储结构——链表
2024/3/28
13
链表定义及特点
1
链表是一种物理存储单元上非连续、非顺序的存 储结构,数据元素的逻辑顺序是通过链表中的指 针链接次序实现的。
数据结构与算法线性表.ppt
线性结构分类
按操作划分
线性表
• 所有表目都是同一类型结点的线性表 • 不限制操作形式 • 根据存储的不同分为:顺序表,链表
栈(LIFO, Last In First Out)
• 插入和删除操作都限制在表的同一端进行
队列(FIFO, First In First Out)
• 插入操作在表的一端, 删除操作在另一端
bool append(const T value); // 在表尾添加一个元素value,表的长度增1
bool insert(const int p, const T value);
// 在位置p上插入一个元素value,表的长度增1
bool delete(const int p);
// 删除位置p上的元素,表的长度减 1
bool getPos(int & p, const T value)
// 查找值为value的元素并返回其位置
bool getValue(const int p, T& value);
// 把位置p的元素值返回到变量value中
bool setValue(const int p, const T value);// 用value修改位置p的元素值
有序性:各数据元素在线性表中都有自己的位置,且 数据元素之间的相对位置是线性的
线性结构
包括:
简单的
• 线性表 •栈 • 队列 • 散列表
高级的
• 广义表 • 多维数组 • 文件
……
线性结构分类
按访问方式划分
直接访问型(direct access) 顺序访问型( sequential access) 目录索引型(directory access)
(数据结构课件)线性表(顺序存储)
• 10、函数名:DeleteList
时间复杂度分析:
(1) 当pos==0时 :查找值等于item的第一个元素(假定 该元素的数组下标为i),则需比较i+1次;然后从数组下 标i+1到n-1的元素依次前移共n-i-1次;总操作次数为n,故 算法的时间复杂度为O(n)。
(2) 当删除指定位置元素时:不需要查找过程,只需考虑 前移次数。 最好情况:删除表尾元素 O(1) 最坏情况:删除表头元素 O(n) 平均情况:前移(n-1)/2次 O(n)
11、函数名:SortList
形参:顺序表L 返回值:无 功能:对表中n个元素进行排序。 说明:
1)采用插入排序方法; 2)该算法的时间复杂度为O(n2)。
• 插入排序方法的思想:
分为有序表和无序表。 • 初始:有序表为空,无序表有n个元素 • 每次操作:从无序表中取第一个元素插入到有序表中,则
无序表中减少一个元素,有序表中增加一个。 • 最后:无序表为空,有序表中有n个元素。
常用的头文件包含语句:
• #include <iostream.h> //包含cout,cin,cerr函数的说明 • #include <stdlib.h> //包含exit,rand等函数的说明 • #include <iomanip.h> //包含setw等函数的说明 • #include <string.h> //包含所有字符串函数的说明,如
(2) 当pos==-1时 :插入到表尾。 (3) 当1≤pos≤n+1时 :插入到pos位置处。 步骤: 1)判断pos值是否有效; 2)对三种情况分别求出要插入的位置; 3)判断表是否已满,若满则分配空间; 4)从表尾到插入位置,元素依次后移一个位置; 5)插入item; 6)表长+1。
《数据结构实用教程》课件第二章 线性表
if (!L.elem) exit(OVERFLOW);
L.length = 0; L.listsize = LIST_INIT_SIZE; return OK;
} // InitList_Sq
线性表操作 ListInsert(&L, i, e)的实现:
首先分析:
插入元素时, 线性表的逻辑结构发生什么变化?
Status ListInsert_Sq(SqList &L, int i, ElemType e) { // 在顺序表L的第 i 个元素之前插入新的元素e, // i 的合法范围为 1≤i≤L.length+1
……
q = &(L.elem[i-1]);
// q 指示插入位置
for (p = &(L.elem[L.length-1]); p >= q; --p) *(p+1) = *p; // 插入位置及之后的元素右移
线性表是一种最简单的线性结构 线性结构是一个数据元素的有序(次序)集
线性结构的基本特征:
1.集合中必存在唯一的一个“第一元素”; 2.集合中必存在唯一的一个 “最后元素” 3.除最后元素之外,均有 唯一的后继; 4.除第一元素之外,均有 唯一的前驱。
例如:alphabet=(a,b,c,…,z) 和 prime=(2,3,5,7,11,…,97)alphabet是字母表,其结 点是一个英文字母,prime是100以内的素数表,结 点是整型数。且只有一个域的线性表,
在稍复杂的线性表中,一个结点(数据元素)可以由若 干个数据项组成,此时常把结点称为记录,含有大量记录 的线性表以称文件.例如学生登记表(如表2.1所示)可以构成
线性表形式的一个文件。表中每个学生对应一个结构或记录类 型,由学号、姓名、班级、性别、出生年月等数据项组成。
L.length = 0; L.listsize = LIST_INIT_SIZE; return OK;
} // InitList_Sq
线性表操作 ListInsert(&L, i, e)的实现:
首先分析:
插入元素时, 线性表的逻辑结构发生什么变化?
Status ListInsert_Sq(SqList &L, int i, ElemType e) { // 在顺序表L的第 i 个元素之前插入新的元素e, // i 的合法范围为 1≤i≤L.length+1
……
q = &(L.elem[i-1]);
// q 指示插入位置
for (p = &(L.elem[L.length-1]); p >= q; --p) *(p+1) = *p; // 插入位置及之后的元素右移
线性表是一种最简单的线性结构 线性结构是一个数据元素的有序(次序)集
线性结构的基本特征:
1.集合中必存在唯一的一个“第一元素”; 2.集合中必存在唯一的一个 “最后元素” 3.除最后元素之外,均有 唯一的后继; 4.除第一元素之外,均有 唯一的前驱。
例如:alphabet=(a,b,c,…,z) 和 prime=(2,3,5,7,11,…,97)alphabet是字母表,其结 点是一个英文字母,prime是100以内的素数表,结 点是整型数。且只有一个域的线性表,
在稍复杂的线性表中,一个结点(数据元素)可以由若 干个数据项组成,此时常把结点称为记录,含有大量记录 的线性表以称文件.例如学生登记表(如表2.1所示)可以构成
线性表形式的一个文件。表中每个学生对应一个结构或记录类 型,由学号、姓名、班级、性别、出生年月等数据项组成。
数据结构课件之线性表(ppt 86页)
删除算法
int DelList(SeqList *L,int i,ElemType *e)
/*在顺序表L中删除第i个数据元素,并用指针参数e返回其值*/
{ int k;
if((i<1)||(i>L->last+1))
{ printf(“删除位置不合法!”); return(ERROR); }
*e= L->elem[i-1]; /* 将删除的元素存放到e所指向的变量中*/
loc(ai) =loc(a1)+(i-1)×k
8
15.10.2019
顺序存储结构示意图
存储地址
Loc(a1) Loc(a1)+(2-1)k
…
loc(a1)+(i-1)k
…
loc(a1)+(n-1)k
...
loc(a1)+(maxlen-1)k
内存空间状态
a1 a2
…
ai
…
an
9
逻辑地址
1 2
…
i
操作前提:L为未初始化线性表。 操作结果:将L初始化为空表。 操作前提:线性表L已存在。 操作结果:将L销毁。 操作前提:线性表L已存在 。 操作结果:将表L置为空表。
………
}ADT LinearList
6
15.10.2019
2.2 线性表的顺序存储
2.2.1 线性表的顺序存储结构 2.2.2 线性表顺序存储结构上的基本运算
17
15.10.2019
删除算法示意
将线性表(4,9,15,21,28,30,30,42,51,62)中的第5个元素 删除。
序号
1 2 3 4 5 6 7 8 9 10 4 9 15 21 28 30 30 42 51 62
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
(4) 求线性表的长度ListLength(L):返回L中元素 个数。
(5) 输出线性表DispList(L):当线性表L不为空时, 顺序显示L中各结点的值域。
(6) 求 线 性 表 L 中 指 定 位 置 的 某 个 数 据 元 素 GetElem(L,i,&e):用e返回L中第 i(1≤i≤ListLength(L)) 个元素的值。
}
本算法的时间复杂度为O(1)。
L 顺序表
(2) 销毁线性表DestroyList(L) 该运算的结果是释放线性表L占用的内存空间。
void DestroyList(SqList *&L) {
free(L); }
本算法的时间复杂度为O(1)。
(3) 判定是否为空表ListEmpty(L)
该运算返回一个值表示L是否为空表。若L为空 表,则返回1,否则返回0。
中,1为表头元素,10为表尾元素。
2.1.2 线性表的运算
线性表的基本运算如下:
(1) 初始化线性表InitList(&L):构造一个空的线性表 L。
(2) 销毁线性表DestroyList(&L):释放线性表L占用 的内存空间。
(3) 判线性表是否为空表ListEmpty(L):若L为空 表,则返回真,否则返回假。
(7) 定位查找LocateElem(L,e):返回L中第1个值域 与e相等的位序。若这样的元素不存在,则返回值为0。
(8) 插 入 数 据 元 素 ListInsert(&L,i,e): 在 L 的 第 i(1≤i≤ListLength(L)+1)个元素之前插入新的元素e,L 的长度增1。
(9) 删除数据元素ListDelete(&L,i,&e):删除L的第 i(1≤i≤ListLength(L))个元素,并用e返回其值,L的长度 减1。
顺序表示意图
在定义一个线性表的顺序存储类型时,需要定义一 个数组来存储线线表中的所有元素和定义一个整型 变量来存储线性表的长度。
假定数组用data[MaxSize]表示,长度整型变量用 length表示,并采用结构体类型表示,则元素类型为通 用类型标识符ElemType的线性表的顺序存储类型可 描述如下:
当n=0时,表示线性表是一个空表,即表中不包 含任何元素。设序列中第i(i表示位序)个元素为 ai(1≤i≤n)。
线性表的一般表示为:
(a1,a2,…ai,ai+1,…,an)
其中a1为第一个元素,又称做表头元素,a2为 第二个元素,an为最后一个元素,又称做表尾元 素。
例如,在线性表
(1,4,3,2,8,10)
int ListInsert(SqList *&L,int i,ElemType e) { int j;
if (i<1 || i>L->length+1)return 0; i--; /*将顺序表逻辑位序转化为elem下标即物理位序*/ for (j=L->length;j>i;j--) L->data[j]=L->data[j-1];
例2.1 假设有两个集合 A 和 B 分别用两个线性表 LA 和 LB 表示,即线性表中的数据元素即为集合中 的成员。编写一个算法求一个新的集合C=A∪B,即 将两个集合的并集放在线性表LC中。
解:本算法思想是:先初始化线性表LC,将LA的所 有元素复制到LC中,然后扫描线性表LB,若LB的当 前元素不在线性表LA中,则将其插入到LC中。算法 如下:
动次数为0;当i=1时,移动次数为n,达到最大值。在
线性表sq中共有n+1个可以插入元素的地方。假设
pi(= )是在第i个位置上插入一个元素的概率,则在 长度为n的线性表中插入一个元素时所需移动元素的
平均次数为:
p n1
n1 1
n
(n i 1)
(n i 1) O(n)
int ListEmpty(SqList *L) {
return(L->length==0); }
本算法的时间复杂度为O(1)。
(4) 求线性表的长度ListLength(L)
该运算返回顺序表L的长度。实际上只需返回 length成员的值即可。
int ListLength(SqList *L) {
void unionList(List LA,List LB,List &LC) {
int lena,lenc,i; ElemType e; InitList(LC); for (i=1;i<=ListLength(LA);i++)
/*将LA的所有元素插入到Lc中*/ { GetElem(LA,i,e);
O(L->length)或O(n)
(8) 插入数据元素ListInsert(L,i,e)
该运算在顺序表L的第i个位置 (1≤i≤ListLength(L)+1)上插入新的元素e。
思路:如果i值不正确,则显示相应错误信息; 否则将顺序表原来第i个元素及以后元素均后移 一个位置,腾出一个空位置插入新元素,顺序表长 度增1。
i i 1
i1 n 1
2
因此插入算法的平均时间复杂度为O(n)。
(9) 删除数据元素ListDelete(L,i,e)
删除顺序表L中的第i(1≤i≤ListLength(L))个元 素。
思路:如果i值不正确,则显示相应错误信息; 否则将线性表第i个元素以后元素均向前移动一个 位置,这样覆盖了原来的第i个元素,达到删除该元 素的目的,最后顺序表长度减1。
void CreateList(SqList *&L,ElemType a[],int n) /*建立顺序表*/ {
int i; L=(SqList *)malloc(sizeof(SqList)); for (i=0;i<n;i++)
L->data[i]=a[i]; L->length=n; }
2. 顺序表基本运算算法
int LocateElem(SqList *L, ElemType e) {
int i=0; while (i<L->length && L->data[i]!=e) i++; if (i>=L->length) return 0; else return i+1; }
本算法中基本运算为while循环中的i++语句,故时 间复杂度为:
typedef struct
{ ElemType data[MaxSize];
int length; } SqList; /*顺序表类型*/
其中,data成员存放元素,length成员存放线性表的 实际长度。
说明:由于C/C++中数组的下标从0开始,线性表的第i 个元素ai存放顺序表的第i-1位置上。为了清楚,将ai在逻辑 序列中的位置称为逻辑位序,在顺序表中的位置称为物理位 序。
线性表 逻辑结构
顺序表 存储结构
假定线性表的元素类型为ElemType,则每个元素 所占用存储空间大小(即字节数)为sizeof(ElemType), 整个线性表所占用存储空间的大小为:
n*sizeof(ElemType)
其中,n表示线性表的长度。
下标位置 线性表存储空间 存储地址
0
a1
(1) 初始化线性表InitList(L)
该运算的结果是构造一个空的线性表L。实际上只 需将length成员设置为0即可。
void InitList(SqList *&L) //引用型指针
{ L=(SqList *)malloc(sizeof(SqList)); /*分配存放线性表的空间*/ L->length=0;
2.2.1 线性表的顺序存储—顺序表
线性表的顺序存储结构就是:把线性表中的所 有元素按照其逻辑顺序依次存储到从计算机存储 器中指定存储位置开始的一块连续的存储空间中。
这样,线性表中第一个元素的存储位置就是指 定的存储位置,第i+1个元素(1≤i≤n-1)的存储位置 紧接在第i个元素的存储位置的后面。
1
a2
┇
┇
i-1
ai
┇
┇
n-1
an
┇
┇
MaxSize-1
┇
LOC(A) LOC(A)+sizeof(ElemType) LOC(A)+(i-1)*sizeof(ElemType) LOC(A)+(n-1)*sizeof(ElemType)
LOC(A)+(MaxSize-1)*sizeof(ElemType)
return(L->length); }
本算法的时间复杂度为O(1)。
(5) 输出线性表DispList(L)
该运算当线性表L不为空时,顺序显示L中各元素的 值。
void DispList(SqList *L) {
int i; if (ListEmpty(L)) return; for (i=0;i<L->length;i++)
} }
由 于 LocateElem(LA,e) 运 算 的 时 间 复 杂 度 为 O(ListLength(LA)),所以本算法的时间复杂度为:
O(ListLength(LA)*ListLength(LB))。
—顺序表 2.2.2 顺序表基本运算的实现
/*将data[i]及后面元素后移一个位置*/ L->data[i]=e; L->length++; /*顺序表长度增1*/ return 1; }
a0
逻辑位序 1
… ai-1 ai … an-1 …
(5) 输出线性表DispList(L):当线性表L不为空时, 顺序显示L中各结点的值域。
(6) 求 线 性 表 L 中 指 定 位 置 的 某 个 数 据 元 素 GetElem(L,i,&e):用e返回L中第 i(1≤i≤ListLength(L)) 个元素的值。
}
本算法的时间复杂度为O(1)。
L 顺序表
(2) 销毁线性表DestroyList(L) 该运算的结果是释放线性表L占用的内存空间。
void DestroyList(SqList *&L) {
free(L); }
本算法的时间复杂度为O(1)。
(3) 判定是否为空表ListEmpty(L)
该运算返回一个值表示L是否为空表。若L为空 表,则返回1,否则返回0。
中,1为表头元素,10为表尾元素。
2.1.2 线性表的运算
线性表的基本运算如下:
(1) 初始化线性表InitList(&L):构造一个空的线性表 L。
(2) 销毁线性表DestroyList(&L):释放线性表L占用 的内存空间。
(3) 判线性表是否为空表ListEmpty(L):若L为空 表,则返回真,否则返回假。
(7) 定位查找LocateElem(L,e):返回L中第1个值域 与e相等的位序。若这样的元素不存在,则返回值为0。
(8) 插 入 数 据 元 素 ListInsert(&L,i,e): 在 L 的 第 i(1≤i≤ListLength(L)+1)个元素之前插入新的元素e,L 的长度增1。
(9) 删除数据元素ListDelete(&L,i,&e):删除L的第 i(1≤i≤ListLength(L))个元素,并用e返回其值,L的长度 减1。
顺序表示意图
在定义一个线性表的顺序存储类型时,需要定义一 个数组来存储线线表中的所有元素和定义一个整型 变量来存储线性表的长度。
假定数组用data[MaxSize]表示,长度整型变量用 length表示,并采用结构体类型表示,则元素类型为通 用类型标识符ElemType的线性表的顺序存储类型可 描述如下:
当n=0时,表示线性表是一个空表,即表中不包 含任何元素。设序列中第i(i表示位序)个元素为 ai(1≤i≤n)。
线性表的一般表示为:
(a1,a2,…ai,ai+1,…,an)
其中a1为第一个元素,又称做表头元素,a2为 第二个元素,an为最后一个元素,又称做表尾元 素。
例如,在线性表
(1,4,3,2,8,10)
int ListInsert(SqList *&L,int i,ElemType e) { int j;
if (i<1 || i>L->length+1)return 0; i--; /*将顺序表逻辑位序转化为elem下标即物理位序*/ for (j=L->length;j>i;j--) L->data[j]=L->data[j-1];
例2.1 假设有两个集合 A 和 B 分别用两个线性表 LA 和 LB 表示,即线性表中的数据元素即为集合中 的成员。编写一个算法求一个新的集合C=A∪B,即 将两个集合的并集放在线性表LC中。
解:本算法思想是:先初始化线性表LC,将LA的所 有元素复制到LC中,然后扫描线性表LB,若LB的当 前元素不在线性表LA中,则将其插入到LC中。算法 如下:
动次数为0;当i=1时,移动次数为n,达到最大值。在
线性表sq中共有n+1个可以插入元素的地方。假设
pi(= )是在第i个位置上插入一个元素的概率,则在 长度为n的线性表中插入一个元素时所需移动元素的
平均次数为:
p n1
n1 1
n
(n i 1)
(n i 1) O(n)
int ListEmpty(SqList *L) {
return(L->length==0); }
本算法的时间复杂度为O(1)。
(4) 求线性表的长度ListLength(L)
该运算返回顺序表L的长度。实际上只需返回 length成员的值即可。
int ListLength(SqList *L) {
void unionList(List LA,List LB,List &LC) {
int lena,lenc,i; ElemType e; InitList(LC); for (i=1;i<=ListLength(LA);i++)
/*将LA的所有元素插入到Lc中*/ { GetElem(LA,i,e);
O(L->length)或O(n)
(8) 插入数据元素ListInsert(L,i,e)
该运算在顺序表L的第i个位置 (1≤i≤ListLength(L)+1)上插入新的元素e。
思路:如果i值不正确,则显示相应错误信息; 否则将顺序表原来第i个元素及以后元素均后移 一个位置,腾出一个空位置插入新元素,顺序表长 度增1。
i i 1
i1 n 1
2
因此插入算法的平均时间复杂度为O(n)。
(9) 删除数据元素ListDelete(L,i,e)
删除顺序表L中的第i(1≤i≤ListLength(L))个元 素。
思路:如果i值不正确,则显示相应错误信息; 否则将线性表第i个元素以后元素均向前移动一个 位置,这样覆盖了原来的第i个元素,达到删除该元 素的目的,最后顺序表长度减1。
void CreateList(SqList *&L,ElemType a[],int n) /*建立顺序表*/ {
int i; L=(SqList *)malloc(sizeof(SqList)); for (i=0;i<n;i++)
L->data[i]=a[i]; L->length=n; }
2. 顺序表基本运算算法
int LocateElem(SqList *L, ElemType e) {
int i=0; while (i<L->length && L->data[i]!=e) i++; if (i>=L->length) return 0; else return i+1; }
本算法中基本运算为while循环中的i++语句,故时 间复杂度为:
typedef struct
{ ElemType data[MaxSize];
int length; } SqList; /*顺序表类型*/
其中,data成员存放元素,length成员存放线性表的 实际长度。
说明:由于C/C++中数组的下标从0开始,线性表的第i 个元素ai存放顺序表的第i-1位置上。为了清楚,将ai在逻辑 序列中的位置称为逻辑位序,在顺序表中的位置称为物理位 序。
线性表 逻辑结构
顺序表 存储结构
假定线性表的元素类型为ElemType,则每个元素 所占用存储空间大小(即字节数)为sizeof(ElemType), 整个线性表所占用存储空间的大小为:
n*sizeof(ElemType)
其中,n表示线性表的长度。
下标位置 线性表存储空间 存储地址
0
a1
(1) 初始化线性表InitList(L)
该运算的结果是构造一个空的线性表L。实际上只 需将length成员设置为0即可。
void InitList(SqList *&L) //引用型指针
{ L=(SqList *)malloc(sizeof(SqList)); /*分配存放线性表的空间*/ L->length=0;
2.2.1 线性表的顺序存储—顺序表
线性表的顺序存储结构就是:把线性表中的所 有元素按照其逻辑顺序依次存储到从计算机存储 器中指定存储位置开始的一块连续的存储空间中。
这样,线性表中第一个元素的存储位置就是指 定的存储位置,第i+1个元素(1≤i≤n-1)的存储位置 紧接在第i个元素的存储位置的后面。
1
a2
┇
┇
i-1
ai
┇
┇
n-1
an
┇
┇
MaxSize-1
┇
LOC(A) LOC(A)+sizeof(ElemType) LOC(A)+(i-1)*sizeof(ElemType) LOC(A)+(n-1)*sizeof(ElemType)
LOC(A)+(MaxSize-1)*sizeof(ElemType)
return(L->length); }
本算法的时间复杂度为O(1)。
(5) 输出线性表DispList(L)
该运算当线性表L不为空时,顺序显示L中各元素的 值。
void DispList(SqList *L) {
int i; if (ListEmpty(L)) return; for (i=0;i<L->length;i++)
} }
由 于 LocateElem(LA,e) 运 算 的 时 间 复 杂 度 为 O(ListLength(LA)),所以本算法的时间复杂度为:
O(ListLength(LA)*ListLength(LB))。
—顺序表 2.2.2 顺序表基本运算的实现
/*将data[i]及后面元素后移一个位置*/ L->data[i]=e; L->length++; /*顺序表长度增1*/ return 1; }
a0
逻辑位序 1
… ai-1 ai … an-1 …