第2章 线性表
数据结构第二章:线性表
实现:可用C 实现:可用C语言的一维数组实现
6
V数组下标 0 1
内存 a1 a2
元素序号 1 2
typedef int DATATYPE; #define M 1000 DATATYPE data[M]; 例 typedef struct card { int num; char name[20]; char author[10]; char publisher[30]; float price; }DATATYPE; DATATYPE library[M];
4
{加工型操作 加工型操作} 加工型操作
ClearList( &L ) 初始条件:线性表 L 已存在。 操作结果:将 L 重置为空表。 PutElem( &L, i, &e ) 初始条件:线性表L已存在,1≤i≤LengthList(L)。 操作结果:L 中第 i 个元素赋值同 e 的值 ListInsert( &L, i, e ) 初始条件:线性表 L 已存在,1≤i≤LengthList(L)+1。 操作结果:在 L 的第 i 个元素之前插入新的元素 e,L 的长度增1。 ListDelete( &L, i, &e ) 初始条件:线性表 L 已存在且非空,1≤i≤LengthList(L)。 操作结果:删除 L 的第 i 个元素,并用 e 返回其值,L 的长度减1。 }ADT LIST
3
PriorElem( PriorElem L, cur_e, &pre_e ) 初始条件:线性表 L 已存在。 操作结果:若 cur_e 是 L 中的数据元素,则用 pre_e 返回 它的前驱,否则操作失败,pre_e 无定义。 NextElem( NextElem L, cur_e, &next_e ) 初始条件:线性表 L 已存在。 操作结果:若 cur_e 是 L 中的数据元素,则用 next_e 返 回它的后继,否则操作失败,next_e 无定义。 GetElem( GetElem L, i, &e ) 初始条件:线性表 L 已存在,1≤i≤LengthList(L)。 操作结果:用 e 返回 L 中第 i 个元素的值。 LocateElem( LocateElem L, e, compare( ) ) 初始条件:线性表 L 已存在,compare( ) 是元素判定函数。 操作结果:返回 L 中第1个与 e 满足关系 compare( ) 的元 素的位序。若这样的元素不存在,则返回值为0。 ListTraverse(L, visit( )) ListTraverse 初始条件:线性表 L 已存在,visit( ) 为元素的访问函数。 操作结果:依次对 L 的每个元素调用函数 visit( )。 一旦 visit( ) 失败,则操作失败。
《数据结构与算法(C++语言版)》第2章 线性表
数据结构与算法 (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章线性表
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、其它操作 复制、分解、合并、分类等
线性表ppt
假设在主函数中已经建立了线性表结构体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】巳知有两个按元素值递增有序的顺序表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
第02章线性表(I)
{ int i;
if(slt->size==MAXSIZE)
{printf("\n顺序表是满的!没法插入!");exit(1);}
if(position<0||position>slt->size)
{printf("\n指定的插入位置不存在!");exit(1);}
for(i=slt->size;i>position;i--) slt->a[i]=slt->a[i−1];
将有序顺序表L1分裂成两个线性表L2与L3,L2由表 中所奇数组成,L3由所有偶数组成。
(3)void merge(sequence_lsit *l1,sequence_list *l2, sequence_list *l3)
将有序顺序表L1与L2合并成有序顺序表L3。
退出
2.3.1栈
2.3 栈
栈是一种特殊的线性表,对于这种线性表规定它
n 1 2
这表明,在一个长为n的顺序表中删除一个元素平 均需要移动表中大约一半的元素。该算法的时间复杂 度为O(n)。
退出
顺序表上的一些其它常见算法
(1)void verge(sequence_list l) 将顺序表L就地转置,即借助于O(1)的辅助空间
。 (2)void sprit(sequence_lsit *l1,sequence_list *l2, sequence_list *l3) [略]
退出
要删除顺序表中的第i个结点,则需要称动(n-i-1 )个元素,设删除表中第i个结点的概率为qi,且在表中 每一个位置删除的概率相等,即:
q0=q1=…=qn-1=1/n
则在一个长度为n的顺序表中删除一个结点的平均 移动次数为:
第2章演示
2.2 线性表的顺序表示和实现 一、顺序表 3.顺序表类型定义 注意: ①存放线性表结点的向量空间的大小MaxSize应仔细 选值,使其既能满足表结点的数目动态增加的需求, 又不致于预先定义过大而浪费存储空间。 ② 由于C语言中向量的下标从0开始,所以若L是 SqList类型的顺序表,则线性表的开始结点a1和终端 结点an分别存储在L.data[0]和L.data[L.length-1]中。 ③若L是SqList类型的指针变量,则a1和an分别存储在 L->data[0]和L->data[L->length-1]中。 ④顺序表的的特点是逻辑上相邻的结点其物理位置亦 相邻。
单链表 6、指针变量和结点变量
注意:指针变量p与结点变量*p的关系。 指针变量p的值是地址; 结点变量*p的值是结点内容。
单链表 6、指针变量和结点变量
说明: ①生成结点变量空间的标准函数 p=( Lnode *)malloc(sizeof(Lnode)); //函数malloc分配一个类型为Lnode的结点变量的 空间,并将其首地址放入指针变量p中 ②释放结点变量空间的标准函数 free(p);//释放p所指的结点变量空间
2.1 线性表的类型定义
2.1 线性表的类型定义 二、线性表的逻辑结构特征 对于非空的线性表: ① 有且仅有一个开始结点a1,没有直接前趋,有且 仅有一个直接后继a2; ② 有且仅有一个终结结点an,没有直接后继,有且 仅有一个直接前趋an-1; ③ 其余的内部结点ai(2≤i≤n-1)都有且仅有一个 直接前趋ai-1和一个直接后继ai+1。
单链表 6、指针变量和结点变量
说明: ③结点分量的访问 利用结点变量的名字*p访问结点分量 方法一:(*p).data和(*p).next 方法二:p-﹥data和p-﹥next
第2章 线性表
数。
第2章 线性表
2.2 线性表的顺序存储结构表示
图2-2所示为线性表在存储介质中顺序分配的情况。
第2章 线性表
逻辑地址 1 2 记录内容 a1 a2 存储地址 LOC(a ) 1 LOC(a )+k 1 内存状况 a1 a2
…
i
…
ai LOC(a )+(i-1)× k 1
…
ai
…
n
图2-2 线性表的顺序分配
第2章 线性表
2.3 线性表元素的操作
2.3.1 线性表元素插入操作 插入一个记录,对有序线性表结构的影响可以从以下 两个方面分析。
(1) 若插入记录关键字的值比表中所有的数据元素的
关键字值都大,那么只需在表后添加一个新记录元素,同 时使表的当前长度修正为n+1即可。
(2) 若插入记录的位置出现在线性表的中间,则情况
LOC(ai)=LOC(a1)+(i-1)×k
从以上的地址计算公式可知,只要已知线性表第 一个数据元素在内存中的存储地址,又知道每一个数 据元素所占存储单元的个数,就能计算出第i个数据元 素在内存中的位置。
第2章 线性表 例如,线性表中第一个数据元素在内存中的地址 LOC(a1)为1000,每一个数据元素占用2个存储单位,
名称“数据结构”的属性就不相同,它们分别为字符
型和数值型。
第2章 线性表 2.1.2 线性表的逻辑结构表示 在任何问题中,数据元素之间可以存在多种关系。 从数据结构的观点来看,重要的是数据元素之间的逻辑 关系。所谓逻辑关系,是指数据元素之间的关联方式或 称“邻接关系”。表2-1中数据的逻辑结构如图2-1(b)所 示,其中的圆圈称为结点。一个结点代表一个数据元素 (有时也把结点和数据元素当作同义词),结点之间的连 线代表逻辑关系,即相应数据元素之间的邻接关系。图 2-1(b)中的逻辑结构反映了表2-1中表格作为一个数据的 组织形式,这种组织形式就是数据元素(记录)“一个接 一个地排列”。
第二章线性表
65
865
姓名
学号
成绩
班级 机97性表
※线性表及运算 ※线性表的存储结构
2.1线性表及运算
线性表是n个元素的有限序列,它们之间的关 系可以排成一个线性序列:
a1,a2,…… ,ai,…… ,an
其中n称作表的长度,当n=0时,称作空表。
线性表的特点:
1.线性表中所有元素的性质相同。 2.除第一个和最后一个数据元素之外,其它数据元 素有且仅有一个前驱和一个后继。第一个数据元 素无前驱,最后一个数据元素无后继。
Status ListInsert_L(LinkList &L,int i, ElemType x){ p=L; j=0; while( p&&j<i-1)
P P
a a
b b
{p=p->next; ++j;}
if( ! p j>i-1) return ERROR;
s=(struct LNode *)malloc(sizeof(struct LNode)); s->data=x; s->next=p->next; p->next=s;
3.数据元素在表中的位置只取决于它自身的序号。
在线性表上常用的运算有:
初始化、求长度、取元素、定位、插 入及删除等。
2.2 线性表的存储结构
1.顺序存储结构
2.链式存储结构
2.1. 线性表的顺序存储结构 ,可用C语言中的一维数组来描述. #define LISTINITSIZE 100 //线性表存储空间的初始分配量
s=(struct LNode *)malloc(sizeof(struct LNode)); s->data=x; s->next=p->next; p->next=s;
第2章 线性表
MaxSize-1
说明:SqListClass<T>的模板类的一个对象L称为顺序 表对象L,也简称为顺序表L,其中主要有data、length数据 成员和相关的运算函数,通过L.data或L.length对数据成员进 行操作,后面的顺序栈、顺序队、顺序串等都采用相似的方 式。
(6)插入数据元素ListInsert(i,e) 该运算在线性表中逻辑序号为i的位臵上插入一个新元素 e。如图2.4所示是插入元素的示意图,由此看出,在一个线 性表中,可以在两端及中间任何位臵上插入一个新元素。
ቤተ መጻሕፍቲ ባይዱ
template <typename T> bool SqListClass<T>::ListInsert(int i, T e) //插入数据元素 { int j; if (i<1 || i>length+1) return false; //参数错误时返回false for (j=length;j>=i;j--) //将data[i-1]及后面元素后移一个位臵 data[j]=data[j-1]; data[i-1]=e; //插入元素e length++; //顺序表长度增1 return true; //成功插入返回true }
(5)按元素值查找LocateElem(e) 该运算顺序查找第一个值与e相等的元素的逻辑序号。若 顺序表中不存在这样的元素,则返回值为0。对应的算法如下:
template <typename T> int SqListClass<T>::LocateElem(T e) //按元素值查找其序号 { int i=0; while (i < length && data[i]!=e) i++; //查找元素e if (i>=length) return 0; //未找到时返回0 else return i+1; //找到后返回其逻辑序号 }
数据结构导论 第2章 线性表
线性表是一种线性结构,线性结构的特点是数据元 素之间是一种线性关系,数据元素“一个接一个的 排列”。 线性结构是n(n>=0)个结点的有穷序列。对于 n>0的线性结构表示成: (a1,a2,… ai-1,ai,ai+1,…an) a1称为起始结点 an称为终端结点 起始结点, 终端结点; 起始结点 终端结点 ai-1 称为 ai 的直接前趋 i+1 称为 ai 的直接后继 直接前趋,a 直接后继。 直接前趋 直接后继
4.查找(定位) locate(L,x): .查找(定位) :
依次将顺序表L中的每个元素与给定的值x进行比 较。若找到则返回其序号(下标+1),否则返回0。 int locate (sqlist L, datatype x) { int i; for ( i=0; i<st; i++) if (L.data[i]==x) return (i+1); return(0); }
void insert (sqlist *L, datatype x, int i ) { if (i<1 || i>L->last+1) error (“插入位置错误”); else if (L->last==maxsize) error (“溢出”); else { for (j=L->last-1; j>=i-1; j--) //往后移动元素 //往后移动元素 L->data[j+1]=L->data[j]; L->data[i-1]=x; //插入x L->last++; //修改表长 } }
常见的线性表的基本运算有以下几个: 常见的线性表的基本运算有以下几个:
第2章 线性表
本算法的时间复杂度为O(1)。
(5) 输出线性表DispList(L) 该运算当线性表L不为空时,顺序显示L中各元素的 值。
void DispList(SqList *L)
{
int i; if (ListEmpty(L)) return;
for (i=0;i<L->length;i++)
printf("%c",L->data[i]); printf("\n");
⑤ 将表的长度加1。
(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。
(3) 判线性表是否为空表ListEmpty(L):若L为空 表,则返回真,否则返回假。
(4) 求线性表的长度ListLength(L):返回L中元素 个数。
(5) 输出线性表DispList(L):当线性表L不为空时, 顺序显示L中各结点的值域。 (6) 求 线 性 表 L 中 指 定 位 臵 的 某 个 数 据 元 素 GetElem(L,i,&e):用e返回L中第 i(1≤i≤ListLength(L)) 个元素的值。
线性表的存储示意图
1. 建立顺序表 其方法是将给定的含有n个元素的数组的 每个元素依次放入到顺序表中,并将n赋给顺 序表的长度成员。算法如下:
数据结构 第二章__线性表(本)
数据结构与算法华东师范大学计算机系杨沛第二章线性表2.1 线性表的基本概念线性表是具有相同数据类型的数据元素的有限序列。
由n(n≥0)个数据元素k0,k1,…,kn-1组成的线性表记为(k0 ,k1 ,…,kn-1),线性表中包含的数据元素的个数n称为线性表的长度(length),称长度为零的线性表为空的线性表(简称为空表)。
相关概念:表头、表尾、前驱、后继有序线性表:数据元素的相对位置与它们的值有联系。
无序线性表:数据元素的相对位置与它们的值没有联系。
第二章线性表例小于20的质数组成的线性表(2,3,5,7,11,13, 17,19);英文字母表也是线性表,表中每个字母是一个数据元素:(A,B,C,……,Z);2.2 顺序表2.2.1 线性表顺序表(sequential list)就是顺序存贮的线性表,即用一组连续的存贮单元依次、连续地存贮线性表中的结点。
如果每个结点占用s个存贮单元,并假设存放结点ki(0≤i≤n-1)的开始地址为loc(k0),则结点ki的地址loc(ki)可表示成Loc(ki) =loc(k0) + i*s。
2.2 顺序表在C 语言中,可用数组表示线性表:#define MAXN 100int list[MAXN];int n;线性表的结点k 0,k 1,…,k n-1依次存放在数组单元list[0],list[1],…,list[n-1]。
2.2.1 线性表最大表长实际表长线性表2.2 顺序表2.2.1 线性表假设s=sizeof(int),则可得到计算ki的地址的公式,因loc(ki)=&list[i],而&list[i]=&list[0]+i·s,故loc(ki)=&list[0]+i·s。
2.2 顺序表2.2.2 顺序表的操作(1)初始化:初始长度置为0即可(n=0;),数组空间在编译时分配。
(2)顺序表的插入:插入算法的C函数SqListInsert():若插入位置i不在可以插入的位置上,即i<0或i>n,则返回0;若n=MAXN,即线性表已满,此时数组list[]没有多余的存贮单元可以存放新结点,则返回-1;若插入成功,则返回12.2 顺序表实际表长(2)顺序表的插入:int SqListInsert(int list[],int*p_n,int i,int x) {int j;if(i<0||i>*p_n)return(0);//i不是合法的插入位置if(*p_len==MAXN)return(-1);//线性表已满2.2 顺序表for(j=*p_n;j>i;j--)list[j]=list[j-1];//结点右移list[i]=x;(*p_n)++;//表长加1return(1);}2.2 顺序表(2)顺序表的插入:对于存放在数组list[]中的、具有n个结点的顺序表,为了把值为x的结点插在表的位置i(0≤i≤n)上,可调用如下的语句:k=SqListInsert(list, &n, i, x);注:结点移动是本算法的关键操作2.2 顺序表(3)顺序表的删除:删除算法的C函数SqListDelete():在具有n个结点的顺序表中,删除第i(0≤i≤n-1)个位置上的结点,使线性表长度减1,若删除位置不合法,即i<0或i≥n,则返回0;若删除位置合法,即0≤i≤n-1,则删除成功,返回1。
数据结构(第二章 线性表)
2.2 线性表的顺序存储和实现
顺序表-顺序表定义
由上可知,数据的存储逻辑位置由数组的下标决定。 所以相邻的元素之间地址的计算公式为(假设每个数 据元素占有d个存储单元): LOC(ai)=LOC(ai-1)+d 对线性表的所有数据元素,假设已知第一个数据元 素a0的地址为LOC(a0) ,每个结点占有d个存储 单元, 则第i个数据元素ai的地址为: LOC(ai)=LOC(a0)+i*d 线性表的第一个数据元素的位置通常称做起始位置 或基地址。 在使用一维数组时,数组的下标起始位置根据给定 的问题确定,或者根据实际的高级语言的规定确定。
2.1 线性表抽象数据类型
线性表的分类
顺序存储结构 (元素连续存储、 随机存取结构) 线性表 ADT 链式存储结构 (元素分散存储) 继承 顺序表类 排序顺序表类 继承 单链表类 循环单链表 双链表 继承 排序循环双链表类 排序单链表类
单链表
双链表
循环双链表类
线性表的存储结构
2.2 线性表的顺序存储和实现
线性表的基本操作 求长度:求线性表的数据元素个数。 访问:对线性表中指定位置的数据元素进行存取、替 换等操作。 插入:在线性表指定位置上,插入一个新的数据元素, 插入后仍为一个线性表。 删除:删除线性表指定位置的数据元素,同时保证更 改后的线性表仍然具有线性表的连续性。 复制:重新复制一个线性表。 合并:将两个或两个以上的线性表合并起来,形成一 个新的线性表。 查找:在线性表中查找满足某种条件的数据元素。 排序:对线性表中的数据元素按关键字值,以递增或 递减的次序进行排列。 遍历:按次序访问线性表中的所有数据元素,并且每 个数据元素恰好访问一次。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
算法与数据结构
2.2 线性表的存储结构及实现
一、线性表的存储结构(顺序表) 二、顺序表数据类型描述 三、顺序表上实现的基本操作 四、顺序表应用举例 五、优缺点分析
2013年8月1日星期四
11
School of Computer and Communication
算法与数据结构
一、顺序表 把线性表的数据元素按 逻辑顺序依次存放在一组地址 连续的存储单元里。 存储结构示意图:
2013年8月1日星期四
i 1
28
四、顺序表应用举例
例2-1 有两个顺序表La和Lb,其元素均 为非递减有序排列,试编写一个算法, 将它们合并成一个顺序表Lc,要求Lc 也是非递减有序排列。
例如:La=(3,5,7,9), Lb=(1,4,6,10,11), 则Lc=(1,3,,4,5, 6,7,9,10,11)。
例、学生情况登记表如下:
姓 名 学 号 性 别 年龄 健康情况
张 王 李
赵 ……..
790631 790632 790633
790634 ……..
男 女 男
男 …….
3
18 20 21
17 …….
健康 一般 健康
神经衰弱 …….
2013年8月1日星期四
School of Computer and Communication
2013年8 of Computer and Communication
算法与数据结构
存储地址 d d+L d+2L ... d+(i-1)L ... d+(n-1)L ...
2013年8月1日星期四
内存单元 ... a1 a2 a3 ·· · ai ·· · an ...
2013年8月1日星期四
29
School of Computer and Communication
算法与数据结构
void merge(SeqList La, SeqList Lb, SeqList *Lc) { int i=0, j=0, k=0; while (i<La.length&&j<Lb.length) if (La.data[i]<=Lb.data[j]) { Lc.data[k]= La.data[i]; i++; k++; }
2013年8月1日星期四
15
三、顺序表上实现的基本操作 1. 查找操作
1)按序号查找Data(L,i) DataType GetData(SeqList L, int i) { /* 查找线性表中的第i个元素*/ If (i<1||i>L.length) printf(“position i error\n”); else return L.data[i-1]; /* 返回表中第i个 元素L.data[i-1] */ }
2013年8月1日星期四
26
School of Computer and Communication
算法与数据结构
• 结点的移动次数也是由表长n和位臵 i决定。 若i=n,算法的最好时间复杂度分 别为O(1) ; 若i=1,则前移语句将循环执行n-1 次,需移动表中除开始结点外的所有 结点,算法的最坏时间复杂度分别为 O(n)。
算法与数据结构
一、线性表的定义 线性表(Linear List) 是由n(n≧0) 个类型相同的数据元素 a1,a2, …,an组成的有限有序序列。 其中数据元素的个数n定义为表 的长度。当n=0时称为空表(又 称为空线性表)。
2013年8月1日星期四
4
School of Computer and Communication
2013年8月1日星期四
i 1
23
3、删除 线性表的删除运算是指将表的 第i(1≦i≦n)个结点删除,使长度为 n的线性表: (a1,…a i-1,ai,a i+1…,an) 变成长度为n-1的线性表: (a1,…a i-1,a i+1,…,an)
2013年8月1日星期四
24
School of Computer and Communication
14
School of Computer and Communication
算法与数据结构
二、顺序表数据类型描述
# define MaxSize 100 /* 线性表存储空间的初始分配量*/ typedef struct Sqlist{ DataType data[MaxSize ]; /* 将线 性表定义为一个一维数组*/ int length; // 当前长度 } Seqlist;
算法与数据结构
DeleteList(Seqlist L,int i,DataType *e) { int j; if(i<1 || i>L.length){ printf(“Position error”); return ERROR; } // if,删除位置不合法 e=&L.data[i-1]; // 被删除元素的值赋给 e
31
while (j<Lb.length) /*当表LB有剩余元素时,则将表LB余下的 元素赋给表LC*/ { Lc.data[k]= Lb.data[j]; j++; k++; } Lc.length=La.length+Lb.length; }
2013年8月1日星期四
16
2)按值查找Locate(L,e) int Locate(SeqList L, DataType e) { i=0 ; while ((i<=L.length-1)&&(L.data[i]!=e) ) i++; if (i<L.length) return(i+1); //成功 else return(-1); //不成功 }
2013年8月1日星期四
6
School of Computer and Communication
算法与数据结构
二、线性表的基本操作 •数据结构的运算是定义在逻 辑结构上的,而运算的具体 实现则是在存储结构上进行 的。
2013年8月1日星期四
7
School of Computer and Communication
2013年8月1日星期四
9
School of Computer and Communication
算法与数据结构
2.1 线性表的定义 2.2 线性表的顺序存储结构及实现
2.3 线性表的链式存储结构及实现 2.4 顺序表和链表的比较 2.5 一元多项式的表示及相加
2013年8月1日星期四
10
School of Computer and Communication
2013年8月1日星期四
25
School of Computer and Communication
算法与数据结构
for(j=i;j<=L.length-1;j++) L.data[j-1]=L.data[j]; /*被删除 元素之后的元素左移*/ L.length--; // 表长减1 return ok; } //DeleteList
算法与数据结构
for(j=L.length-1;j>=i-1;j--) L.data[j+1] = L.data[j]; /*插入位 置及之后的元素右移*/ L.data[i-1] = x; // 插入x L.length++; // 表长增1 return ok; } //InsertList
2013年8月1日星期四
13
School of Computer and Communication
算法与数据结构
特点:(1)存储单元连续; (2)利用数据元素的存储位臵表示 线性表中相邻数据元素之间的前后 关系,即线性表的逻辑结构与存储 结构(物理结构)一致; (3)随机存储结构; (4) 存储的密度大。
2013年8月1日星期四
2013年8月1日星期四
27
School of Computer and Communication
算法与数据结构
在长度为n的线性表中删除一个结点, 令Ede(n)表示所需移动结点的平均次数, 删除表中第i个结点的移动次数为n-i, n 故 Ede(n)= pi(n-i)
式中,pi表示删除表中第i个结点的概率. 在等概率可得:n Ede(n)= (n-i)/n=(n-1)/2 i 1 即平均时间复杂度也是O(n)。
2013年8月1日星期四
18
School of Computer and Communication
算法与数据结构
InsertList(Seqlist L,DataType x, int i) { if(i<1 || i>L.length+1){ //位臵非法 printf(“Position error”); return ERROR; } //if
2013年8月1日星期四
30
else{ Lc.data[k]=Lb.data[j]; j++; k++; } while (i<La.length) /*当表LA有剩余元素时,则将表LA 余下的元素赋给表LC*/ { Lc.data[k]= La.data[i]; i++; k++; }
2013年8月1日星期四
简单数据结构 第二章 线性表
2013年8月1日星期四
1
School of Computer and Communication
算法与数据结构
2.1 线性表的定义