第02讲 线性表类型定义与顺序表
线性表的类型定义、顺序表示和实现

i=n 只删 an即可 1≤i≤n -1 将ai+1 ~an前移
23
bool deleteElem(SqList& L,int pos)
typedef int ElemType;
typedef char ElemType;
等;
②同一线性表中的数据元素必须具有相同的特性,属同一类 型;
③a2,关…系, ra是i-1,一a个i, a有i+1序, …偶,对an的)集,合a,i-1即领对先于于非ai,空表的示线了性数表据(元a1,素 之间的相邻关系,称ai-1是ai的直接前驱,ai是ai-1的直接后继 ;
6
2.1.3 操作举例
例:假设利用两个线性表La和Lb分别表示两 个集合A和B,求一个新的集合A=A∪B。
算法:
– ①取得Lb中的1个元素; – ②在La中查找这个元素; – ③若不存在:插入La中;若存在,取Lb中下一个
元素,重复 ①、②、③,直到取完Lb的每个元素 。
7
void unionList(SqList &la,SqList lb)
10
线性表的顺序存储结构示意图
存储地址
loc(a1) loc(a1)+ k
内存空间状态 逻辑地址
a1
1
a2
2
…
…
…
loc(a1)+ (i- 1)k
ai
i
…
…
…
loc(a1)+ (n- 1)k
an
n 空闲
顺序存储结构可以借助于高级程序设计语言中的一维数组来表示。
11
用C++语言描述的顺序表类型如下所示: sqlist.h
第二章 线性表

(7)已知顺序表L中的元素有序递增,设计算法将元素x插入到L 种,并依旧保持其有序递增;设计一个高效的算法,删除顺序表 中所有值为x的元素,要求空间复杂度为O(1)。(基于顺序表基本 操作的运算) (8)(2010年13分)设将n(n>1)个整数存放到一维数组R中。试 设计一个在时间和空间两方面尽可能有效的算法,将R中保有的 序列循环左移P(0<p< n)个位置,即将R中的数据由(X0 X1 ……Xn-1)变换为(Xp Xp+1 ……Xn-1 X0 X1……Xp-1) 要求: (1)给出算法的基本设计思想。 (2)根据设计思想,采用C或C++或JAVA语言描述算法,关键之处 给出注释。 (3)说明你所设计算法的时间复杂度和空间复杂度
2 3 4 5 6
30 60 20 40
6 -1 3 1
h
10
20Βιβλιοθήκη 304050
60∧
8、例题: (1)链表不具有的特点是( )。 A.可随机访问任一元素 B.插入删除不需要移动元素 C.不必事先估计存储空间 D.所需空间与线性表长度成正比 (2)在具有n个结点的单链表中插入一个新结点并使链表仍然有 序的时间复杂度是( )。 A. O(1) B. O(n) C. O(nlog2n) D. O(n2) (3)对于由n个元素组成的线性表,创建一个有序单链表的时间 复杂度是( )。 A. O(1) B. O(n) C. O(nlog2n) D. O(n2)
(4)设A是一个线性表,采用顺序存储结构。在等概率情况下, 平均插入一个元素需要移动多少个元素?若元素插在ai和ai+1之 间的概率为(n-i)/n(n-1)/2,则平均插入一个元素需要移动多少 个元素? (5)以顺序表作为存储结构,实现线性表的就地逆置;判断回 文;设计一个时间复杂度为O(n)的算法,将顺序表中所有元素循 环左移k位;设计一个时间复杂度为O (n)的算法,将顺序表中所 有元素循环右移k位;(基于逆置操作的运算) (6)将顺序表中的元素调整为左右两部分,左边元素为奇数, 右边元素为偶数,要求算法的时间复杂度为O (n);将顺序表A拆 分为B 和C,其中B中的元素小于0,C中的元素大于0;将有序表A和 有序表B合并为C,合并后C依然是有序的。(基于对顺序表的拆分 和合并操作的运算)
2.1 线性表的类型定义1.线性表的定义 是由n(n=0)个数据元素a1.

18
20 21
健康
一般 健康
张立立
……..
790634
……..
男
…….
17
…….
神经衰弱
…….
3
• 注意:
(1)线性表中的所有数据元素的数据类型是一致的。 (2)数据元素在线性表中的位置只取决于它的序号。 (3)相邻数据元素之间存在着序偶关系。 (4)结点间的逻辑关系是线性的。
4
3.抽象数据类型线性表的定义如下:
11
(2)插入运算 在第i(1<=i<=n+1)个元素之前插入一个新的数据元素x。 使长度为n的线性表变为长度为n+1的线性表:
(a1,a2,…,ai-1,ai,…,an)
(a1,a2,…,ai-1,x, ai,…,an)
12
•
插入算法的思想:
1. 将线性表中的第i个至第n个数据元素后移一个位置(共需 移动n-i+1个数据元素),
1
2.线性表(a1,a2,a3, ……an)的特点:
在数据元素的非空有限集中, (1)存在唯一的一个被称为“第一个”的数据元素; (2)存在唯一的一个被称为“最后一个”的数据元素; (3)除第一个之外,集合中的每个数据元素均只有一个 前驱; (4)除最后一个外,集合中的每个数据元素均只有一个 后继。 线性表中的数据元素类型多种多样,但同一线性表 中的元素必定具有相同特性,在一些复杂的线性表中, 每一个数据元素又可以由若干个数据项组成,在这种情 况下,通常将数据元素称为记录(record)。
10
4.顺序表的几种基本运算
(1)初始化运算 Status InitList_Sq(Sqlist &L){ L.elem=(Elemtype *)malloc (LIST_INIT_SIZE*sizeof(Elemtype)); //分配内存单元 if (! L.elem) exit (OVERFLOW); //存储分配失败 L.Length=0; //空表长度为0 L.Listsize=LIST_INIT_SIZE; //初始存储容量 return OK; }//InitList_Sq
线性表

举例:
La=(34,89,765,12,90,-34,22) 数据元素类型为int。 Ls=(Hello,World, China, Welcome) 数据元素类型为 string。 Lb=(book1,book2,...,book100) 数据元素类型为下列所示的结 构类型: struct bookinfo { int No; //图书编号 char *name; //图书名称 char *auther; //作者名称 ...; };
素的方法被称为随机存取法,使用这种存取方法的存储结构被
称为随机存储结构。
在C语言中,实现线性表的顺序存储结构的类型定义
typedef int ElemType; //定义顺序表中元素的类型 #define INITSIZE 100 //顺序表存储空间初始分配量 #define LISTINCREMENT 10 //线性表存储空间的分配增量 typedef struct { ElemType *data; int length; //存储空间的基地址 //线性表的当前长度
说明:
1. 某数据结构上的基本运算,不是它的全部运算,而是一些 常用的基本的运算,而每一个基本运算在实现时也可能根据不 同的存储结构派生出一系列相关的运算来, 没有必要全部定义 出它的运算集。掌握了某一数据结构上的基本运算后,其它的 运算可以通过基本运算来实现,也可以直接去实现。 2. 在上面各操作中定义的线性表L仅仅是一个抽象在逻辑结 构层次的线性表,尚未涉及到它的存储结构,因此每个操作在 逻辑结构层次上尚不能用具体的某种程序语言写出具体的算法, 而算法的实现只有在存储结构确立之后。
4. 求顺序表的长度 int getlen(sqlist L) { return (L.length); } 5. 判断顺序表是否为空 int listempty(sqlist L) { if (L.length==0) return 1; else return 0; }
线性表

2.1 线性表的类型定义
例3:下图为10个个学生的成绩表,它也是一个 线性表,该线性表的数据元素类型为结构体类型。
2.1 线性表的类型定义
从以上例子可看出线性表的逻辑特征是: 在非空的线性表中,有且仅有一个被称作 “第一个”的数据元素a1,它没有直接前趋, 而仅有一个直接后继a2; 有且仅有一个被称作“最后一个”的数据元 素an,它没有直接后继,而仅有一个直接前 趋 a n-1; 其余的数据元素ai(2≦i≦n-1)都有且仅有一个 直接前趋a i-1和一个直接后继a i+1。 线性表是一种典型的线性结构。
2.2 线性表的顺序表示和实现
#define MAXNUM 100 Elemtype List1[MAXNUM] ; /*定义线性表L1*/ int length1;
Elemtype List2[MAXNUM] ; /*定义线性表L1*/ int length2;
Elemtype List3[MAXNUM] ; /*定义线性表L1*/ int length3;
2.2 线性表的顺序表示和实现
而只需要将数组和表长封装在一个结构体中,然 后定义三个结构体变量即可: struct L_list { Elemtype List[MAXNUM]; int length; }; struct L_list L1, L2, L3; /*定义三个线性表L1,L2,L3*/
2.1 线性表的类型定义
例1:26个英文字母组成的字母表 (A,B,C、…、Z) 例2:某公司2000年每月产值表(单位:万元) (400,420,500,…,600,650) 是一个长度为12的线性表。
上述两例中的每一个数据元素都是不可分割的, 在一些复杂的线性表中,每一个数据元素又可 以由若干个数据项组成。
数据结构线性表

数据结构线性表一、引言数据结构是计算机存储、组织数据的方式,它决定了数据访问的效率和灵活性。
在数据结构中,线性表是一种最基本、最常用的数据结构。
线性表是由零个或多个数据元素组成的有限序列,其中数据元素之间的关系是一对一的关系。
本文将对线性表的概念、分类、基本操作及其应用进行详细阐述。
二、线性表的概念1.数据元素之间具有一对一的关系,即除了第一个和一个数据元素外,其他数据元素都是首尾相连的。
2.线性表具有唯一的第一个元素和一个元素,分别称为表头和表尾。
3.线性表的长度是指表中数据元素的个数,长度为零的线性表称为空表。
三、线性表的分类根据线性表的存储方式,可以将线性表分为顺序存储结构和链式存储结构两大类。
1.顺序存储结构:顺序存储结构是将线性表中的数据元素按照逻辑顺序依次存放在一组地质连续的存储单元中。
顺序存储结构具有随机访问的特点,可以通过下标快速访问表中的任意一个元素。
顺序存储结构的线性表又可以分为静态顺序表和动态顺序表两种。
2.链式存储结构:链式存储结构是通过指针将线性表中的数据元素连接起来,形成一个链表。
链表中的每个节点包含一个数据元素和一个或多个指针,指向下一个或前一个节点。
链式存储结构具有动态性,可以根据需要动态地分配和释放节点空间。
链式存储结构的线性表又可以分为单向链表、双向链表和循环链表等。
四、线性表的基本操作线性表作为一种数据结构,具有一系列基本操作,包括:1.初始化:创建一个空的线性表。
2.插入:在线性表的指定位置插入一个数据元素。
3.删除:删除线性表中指定位置的数据元素。
4.查找:在线性表中查找具有给定关键字的数据元素。
5.更新:更新线性表中指定位置的数据元素。
6.销毁:释放线性表所占用的空间。
7.遍历:遍历线性表中的所有数据元素,进行相应的操作。
8.排序:对线性表中的数据元素进行排序。
9.合并:将两个线性表合并为一个线性表。
五、线性表的应用1.程序语言中的数组:数组是一种典型的顺序存储结构的线性表,常用于存储具有相同类型的数据元素。
线性表_精品文档

线性表什么是线性表?线性表是一种常见的数据结构,它由一系列具有相同数据类型的元素组成。
线性表中的元素之间存在着一对一的线性关系,即每个元素都有唯一的直接前驱和直接后继(除了第一个元素没有直接前驱和最后一个元素没有直接后继)。
线性表可以用来存储一组有序的数据,例如整数、浮点数、字符等等。
它可以通过下标来访问元素,支持插入、删除和查找操作。
线性表的分类线性表可以分为两种基本形式:顺序表和链表。
顺序表顺序表是将线性表的元素按照顺序依次存储在一块连续的存储空间中。
在顺序表中,按照元素插入顺序分为静态顺序表和动态顺序表。
静态顺序表静态顺序表是指事先申请好固定大小的存储空间,用于存储线性表的元素。
静态顺序表的大小在编译时确定,无法动态调整。
当静态顺序表已满时,如果需要插入新的元素,就无法继续插入,需要进行额外的处理。
动态顺序表动态顺序表是指不事先申请固定大小的存储空间,而在需要时进行动态扩容和缩容的顺序表。
动态顺序表的大小可以根据需要动态调整,使得线性表可以动态增长或减少。
链表链表是一种通过指针将线性表的元素链接在一起的数据结构。
链表中的每个元素都包含一个指针,指向下一个元素。
链表的存储空间可以是连续的,也可以是不连续的。
单链表单链表是链表的基本形式。
每个节点包含数据域和指针域,数据域用于存储元素的值,指针域用于指向下一个元素。
链表的头节点没有前驱节点,尾节点没有后继节点。
双链表双链表是在单链表的基础上进行扩展的。
每个节点除了有指向下一个元素的指针,还有指向前一个元素的指针。
双链表可以支持双向遍历和双向操作,但相应地增加了额外的指针域,占用更多的存储空间。
线性表的操作线性表的常用操作包括插入、删除、查找、遍历等。
插入插入操作可以在线性表的指定位置插入一个新的元素。
插入元素时,需要移动后续元素的位置来腾出空间,并调整相应的指针。
插入操作的时间复杂度为O(n)。
删除删除操作可以删除线性表中指定位置的元素。
删除元素时,需要调整前后元素的指针,使得元素之间重新链接。
《数据结构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;
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
例2 : 假已知一个非纯集合B 假已知一个非纯集合B,(即B中包含有相同元 素)试构造一个纯集合A,使A中只包含B中所有值 试构造一个纯集合A 中只包含B 各不相同的数据元素。 各不相同的数据元素。 (假设B为有序序列) 假设B为有序序列)
则思路即为: 则思路即为: 创建一个空的线性表LA; 1) 创建一个空的线性表LA; 从线性表LB中依次取得每个数据元素; LB中依次取得每个数据元素 2) 从线性表LB中依次取得每个数据元素; 3) 依值在线性表LA中进行查访; 依值在线性表LA中进行查访; LA中进行查访 4) 若不存在,则插入之。 若不存在,则插入之。
, a2 , … , ai … , an),
在线性表中的位置。 称 i 为 ai 在线性表中的位置。
线性表的基本操作
1)InitList( &L ) 操作结果:结构初始化,构造一个空的线性表L 操作结果:结构初始化,构造一个空的线性表L 2)DestroyList( &L ) 初始条件:线性表L已存在。 初始条件:线性表L已存在。 操作结果:销毁线性表L 操作结果:销毁线性表L。 3)ListEmpty( L ) 初始条件:线性表L 初始条件:线性表L已存在 操作结果: 为空表,返回TRUE 否则FALSE TRUE, 操作结果:若L为空表,返回TRUE,否则FALSE
问题可演绎为,要求对线性表作如下操作: 问题可演绎为,要求对线性表作如下操作: 扩大线性表LA,将存在于线性表LB中而不存于线 扩大线性表LA,将存在于线性表LB中而不存于线 LA LB 性表LA中的数据元素插入到线性表LA中 性表LA中的数据元素插入到线性表LA中。 LA中的数据元素插入到线性表LA 则思路即为: 则思路即为: 从线性表LB中依次取得每个数据元素; LB中依次取得每个数据元素 1) 从线性表LB中依次取得每个数据元素; 依值在线性表LA中进行查访; LA中进行查访 2) 依值在线性表LA中进行查访; 3) 若不存在,则插入之。 若不存在,则插入之。
9)ListTraverse(L, visit( ))
初始条件:线性表L已存在。 初始条件:线性表L已存在。 操作结果:依次对L的每个元素调用visit()函数。 visit()函数 操作结果:依次对L的每个元素调用visit()函数。 一旦visit()失败, visit()失败 一旦visit()失败,则操作失败
例1:26个英文字母组成的字母表 26个英文字母组成的字母表 (A,B,C, …, Z) , Z) 例2:某校从1978年到1983年各种型号的计算 某校从1978年到1983年各种型号的计算 1978年到1983 机拥有量的变化情况。 机拥有量的变化情况。 17,28,50,92,188) (6,17,28,50,92,188)
a C= b
a<=b a>b
void mergelist(list la, list lb, list &lc){ initlist(lc); i=j=1; k=0; la_len = listlength(la); lb_len = lis (i<=la_len) && (j<=lb_len) ){ getelem(la, i, ai); getelem(lb, j, bj); ++j; } if (ai<=bj) { listinsert(lc, ++k, ai); ++i; } else { listinsert(lc, ++k, bj); } while (i<=la_len) { getelem(la, i++, ai); listinsert(lc, ++k, ai); } while(j<=lb_len) { getelem(lb, j++, bj); listinsert(lc, ++k, bj); } }
7)PriorElem( L, cur_e, &pre_e )
初始条件:线性表L已存在。 初始条件:线性表L已存在。 操作结果: cur_e是 的元素,但不是第一个, 操作结果:若cur_e是L的元素,但不是第一个,则用 pre_e返回它的前驱,否则操作失败,pre_e无定义 pre_e返回它的前驱,否则操作失败,pre_e无定义 返回它的前驱
例3:学生健康情况登记表如下: 学生健康情况登记表如下:
姓名 学号 性别 男 女 男 男 … 年龄 18 20 21 17 … 健康情况 健康 一般 健康 神经衰弱 …
王小林 790631 陈 红 790632
刘建平 790633 张立立 790634 … …
2. 线性表的逻辑特征
非空的线性表中, 1. 非空的线性表中,有且仅有一个开始结点 a1 无直接前趋,并且仅有一个直接后继 a2; 无直接前趋, 无直接后继, 2. 有且仅有一个终端结点 an 无直接后继,并且 仅有一个直接前趋 an-1; (2≤i≤n-1)都有且仅有一 3. 其余的内部结点 ai(2≤i≤n-1)都有且仅有一 个直接前趋 ai-1 和一个直接后继 ai+1。
线性表的基本运算: 线性表的基本运算: 在两个确定的元素之间插入 插入一个新的元 1. 在两个确定的元素之间插入一个新的元 素;删除线性表中某个元素; 删除线性表中某个元素; 线性表中某个元素 查找线性表中的一个元素 按某种要求查找线性表中的一个元素, 2. 按某种要求查找线性表中的一个元素, 需要时,还可对找到的元素进行“ 需要时,还可对找到的元素进行“值” 的更新。 更新。
6)LocateElem( L, e, compare( ) )
初始条件: 已存在,compare()是元素判定函数 初始条件:L已存在,compare()是元素判定函数 操作结果:返回L中第1个与e满足关系compare()的元 操作结果:返回L中第1个与e满足关系compare()的元 compare() 素的位序;若这样的元素不存在,则返回值为0 素的位序;若这样的元素不存在,则返回值为0。
4)ListLength( L )
初始条件:线性表L已存在。 初始条件:线性表L已存在。 操作结果:返回L 操作结果:返回L中元素个数
L,i 5)GetElem( L,i, &e )
初始条件:线性表L已存在, 1≤i≤表长 初始条件:线性表L已存在,且1≤i≤表长 操作结果: 返回L中第i 操作结果:用 e 返回L中第i个元素的值
5.线性表的分类 5.线性表的分类 线性表 顺序表 用顺序存储结构存储的线性表 链 表 用链式存储结构存储的线性表
第2 章
线性表
2.1 线性表的类型定义 2.2 线性表的顺序表示和实现 2.3 线性表的链式表示和实现 2.3.1 线性链表 2.3.2 循环链表 2.3.3 双向链表 2.4 一元多项式的表示及相加
例3:已知线性表LA和LB中的数据元素按值非递减 已知线性表LA和LB中的数据元素按值非递减 LA 有序排列,现要求将LA和LB归并为一个新的线性 有序排列,现要求将LA和LB归并为一个新的线性 LA 表LC,且LC中的元素仍按值非递减有序排列。 LC, LC中的元素仍按值非递减有序排列。 中的元素仍按值非递减有序排列
10) 10)ListInsert( &L, i, e ) 初始条件:线性表L已存在,1≤i≤表长+1 初始条件:线性表L已存在,1≤i≤表长+1 表长 操作结果: 操作结果:在L的第i个元素之前插入新的元 的第i 素e,L的长度增1。 的长度增1 11) 11)ListDelete(&L, i, &e) 初始条件: 已存在且非空,1≤i≤表长 初始条件:L已存在且非空,1≤i≤表长 操作结果:删除L的第i个元素, 操作结果:删除L的第i个元素,用e返回其 值,L的长度减1。 的长度减1 12) 12)ClearList( &L ) 初始条件:线性表L已存在。 初始条件:线性表L已存在。 操作结果: 操作结果:将L重置为空表。 重置为空表。
4.利用上述定义的操作完成更复杂的操作 4.利用上述定义的操作完成更复杂的操作
例1 : 假设有两个集合A 假设有两个集合A和B分别用两个线性表LA和 分别用两个线性表LA和 LA LB表示。(即 LB表示。(即:线性表中的数据元素即为集合中 表示。( 的成员),现要求一个新集合 的成员),现要求一个新集合 ), A=A∪B
void union(List &La, List Lb) { //将所有在线性表Lb中但不在La中的元素插入到La //将所有在线性表Lb中但不在La中的元素插入到La 将所有在线性表Lb中但不在La中的元素插入到 La_len = ListLength(La); Lb_len = ListLength(Lb); for (i = 1; i <= Lb_len; i++) { GetElem(Lb, i, e); //取Lb中第i个元素赋给e //取Lb中第i个元素赋给e 中第 if ( !LocateElem(La, e, equal( )) ListInsert(La, ++ La_len, e); La中不存在和 相同的元素, // La中不存在和 e 相同的元素,则插入之 } } // union
void purge(List &La, List Lb) { 构造La 使其只包含Lb La, Lb中所有值不相同的元素 // 构造La,使其只包含Lb中所有值不相同的元素 InitList(LA); La_len = ListLength(La); Lb_len = ListLength(Lb); for (i = 1; i <= Lb_len; i++) { GetElem(Lb, i, e); // 取Lb中第i个元素赋给e Lb中第 个元素赋给e 中第i en = e; } if( ! equal (en, e) ) { ListInsert(La, ++La_len, e); } } // purge La中不存在和 相同的元素, 中不存在和e // La中不存在和e相同的元素,则插入