第二章 线性表
第二章线性表
//最后元素在数组中的位置(下标值)
} SeqList;
其中elem数组的第 i 个分量为线性表第 i 个 数据元素的存储映像。注意区分元素的序号和 数组的下标,如a1的序号为1,而其对应的数组 下标为0。last 指最后一个数据元素在数组空间 中的位置。空表last置为-1
#define LIST_INIT_SIZE 100//线性存储空间 的初始分配量 #define LISTINCREMENT 10//线性表存储空 间的分配增量
内存空间状态
a1 a2
…
ai
…
an
逻辑地址
1 2
…
i
…
n
...
loc(a1)+(maxlen-1)k
顺序存储结构的C语言定义
#define maxsize=线性表可能达到的最大长度;
typedef struct
{ ElemType elem[maxsize]; // 线性表占用的数组空间
int last;
若没有与e相等的元素,则返回值为0。 Traverse(L,visit( )) 依次对L的每个元素调用函数
visit( )。一旦visit( )失败,则操作失败。
加工型操作
Clear(L) 将L置为空表。 Put(L, i, e ) 将e的值赋给L的 i号元素。
(1≤i≤Length(L) ) InsList(L,i,e) 在L的i号元素(1≤i≤Length(L)+1)
注:这里的数据元素ai(1≤i≤n)只是一个抽象的 符号,其具体含义在不同的情况下各不相同。
例1 26个英文字母组成的字母表: (A,B,C、…、Z)
例2 某校从1978年到1983年各种型 号的计算机拥有量的变化情况:
数据结构第二章:线性表
实现:可用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( ) 失败,则操作失败。
第2章线性表
(1) 将线性表L中的第i+1个至第n个结点依此向前移 动一个位置。
(2) 线性表长度减1。
算法描述
Status Delete_SqList(Sqlist &L,int i, ElemType &e)
{
if (L.length==0) { printf(“线性表L为空!\n”); return ERROR; }
◆ 删除时平均移动次数:Edelete=∑pi*(n-i) (1≦i≦n) ∴ Edelete=(n-1)/2 。
平均时间复杂度:Ecompare+Edelete=n ,即为O(n)
2.3 线性表的链式存储
2.3.1 线性表的链式存储结构
链式存储 :用一组任意的存储单元存储线性表
中的数据元素。用这种方法存储的线性表简称线性链 表。
{ ElemType Elem_array[MAX_SIZE] ; int length ;
} SqList ; 如何?
(3) 用下述结构类型来定义顺序表类型,有何不同? typedef int Status ; typedef int ElemType ; #define LIST_INIT_SIZE 100 #define LISTINCREMENT 10
Status Insert_SqList(Sqlist &L,int i, ElemType e)
{if ( i<1||i>L.length+1) return ERROR ;
if (L.length>=L.listsize)
{ newbase=( ElemType* )realloc(L. elem, (L.listsize+LISTINCREMENT)*sizeof( ElemType ) ) ; if ( !newbase ) exit(OVERFLOW);
数据结构课件第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章 线性表
(9) ListDelete (&L, i, &e)
初始条件: 表L已存在且非空, 1≤i≤ListLength(L)。
操作结果: 删除L的第i个数据元素, 并用e返回其值, L
的长度减1。 } ADT List
第2章 线 性 表 例2—1 Void union (List &La, List Lb){ La_len= ListLength (La); Lb_len= ListLength (Lb); For (i=1;i<= Lb_len;i++){ GetElem (Lb,i,e); If(!LocateElem(La,e,equal)) ListInsert(La,++ La_len,e); } } O(Listlength(LA)* Listlength(LB))
第2章 线 性 表
假设线性表中有n个元素,每个元素占k个单元,第一
个元素的地址为loc(a1),则可以通过如下公式计算出第i个
元素的地址loc(ai):
loc(ai) =loc(a1)+(i-1)×k
其中loc(a1)称为基地址。 它是一种随机存取的数据结构。
第2章 线 性 表
存储地址 loc(a1 ) loc(a1 )+k 内存空间状态 a1 a2 逻辑地址 1 2
构类型但同一线性表中的数据元素必须属于同一数据对象。此外,
线性表中相邻数据元素之间存在着序偶关系,即对于非空的线性
表(a1, a2, …,ai-1, ai, ai+1, …, an), 表中ai-1 领先于ai,称ai-1 是ai 的直接前驱,而称ai是 ai-1的直接后继。除了第一个元素a1外,每
第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-第2章线性表第1讲-线性表的基本概念
Lb_len = ListLength(Lb);
while(i <= La_len && j <= Lb_len) { // 表La和表Lb均非空
GetElem(La, i, ai);
GetElem(Lb, j, bj);
if(ai <= bj) {
ListInsert(Lc, ++k, ai);
++i;
【示例2-1】利用两个线性表LA和LB分别表示两个集合 A和B,现要求一个新的集合A=A∪B。
代码实现:
void Union(SqList &La, SqList Lb)
{
ElemType e;
int La_len, Lb_len;
int i;
La_len = ListLength(La);
// 求线性表的长度
求线性表中第i个元素GetElem(L,i,e)。其作用是 返回线性表L的第i个数据元素。
按值查找LocateElem(L,x)。若L中存在一个或多个 值与x相等的元素,则其作用是返回第一个值为x的元 素的逻辑序号。
插入元素ListInsert(L,i,x)。其作用是在线性表L 的第i个位置上增加一个以x为值的新元素
}
else {
ListInsert(Lc, ++k, bj);
++j;
}
}
// 以下两个while循环只会有一个被执行
while(i <= La_len) {
// 表La非空且表Lb空
GetElem(La, i++, ai);
ListInsert(Lc, ++k, ai);
第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章 线性表
线性表是一种线性结构,线性结构的特点是数据元 素之间是一种线性关系,数据元素“一个接一个的 排列”。 线性结构是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赋给顺 序表的长度成员。算法如下:
第二章 线性表
Delete(p, L ) ; else
p = Next(p, L ) ; } }
2020/11/15
哈工大计算机科学与技术学院 张岩
Slide 2-8
else
last
return ( L.elements[ p ] ) ;
} //时间复杂性:O(1)
max-1
2020/11/15
哈工大计算机科学与技术学院 张岩
//// a1 a2 ….
ai ….
an
Slide 2-17
第2章 线性表
2.2线性表的存储结构----顺序表(Cont.)
其他操作的实现
2020/11/15
哈工大计算机科学与技术学院 张岩
Slide 2-6
第2章 线性表
2.1 线性表的逻辑结构(Cont.)
定义在线性表的操作(算法): 设L是类型为LIST线性表实例,x 的型为ElemType的元素 实例,p 为位置变量。所有操作描述为: ① Insert(x, p, L) ② Locate(x, L) ③ Retrieve(p, L) ④ Delete(p, L) ⑤ Previous(p, L) ⑥ Next(p, L) ⑦ MakeNull( L) ⑧ First( L) ⑨ END(L)
第2章 线性表
2.2线性表的存储结构----顺序表(Cont.)
其他操作的实现
position MakeNull( LIST &L ) //⑦
{ st = 0 ;
return ( st +1 );
数据结构讲义第2章-线性表
t个单元
a1 a2 ai-1 ai ai+1 an
2.2 线性表的顺序存储和实现
线性表的顺序存储结构——顺序表 一 线性表的顺序存储结构 顺序表
顺序表的定义: 一维数组+表长
例1: 写出线性表(6,17,28,50,92,188)的顺序 存储结构表示。 # define ListSize 100 typedef int ElemType; ElemType List[ListSize]; int length;
思考:采用其它的定义如何初始化空表?
2.2 线性表的顺序存储和实现
三 顺序表应用举例
1. 设有两个按元素值递增有序排列的顺序表A和B,请编写算法将A 和B归并成一个按元素值递增有序排列的线性表C。 void merge(SeqList A,SeqList B,SeqList &C) {i=0;j=0;k=0; while ( i<A.length && j<B.length ) if (A.data[i]<B.data[j]) C.data[k++]=A.data[i++]; else C.data[k++]=B.data[j++]; while (i<A.length ) C.data[k++]= A.data[i++]; while (j<B.length ) C.data[k++]=B.data[j++]; C.length=k; }
调用示例: main() {SeqList L; ElemType e; ... delete_ListSq(L,2,e); ... }
数据结构 第二章__线性表(本)
数据结构与算法华东师范大学计算机系杨沛第二章线性表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。
数据结构第二章线性表
线性表的顺序存储结构可用数组来实现。 数组元素的类型就是线性表中数据元素 的类型,数组的大小,最好大于线性表 的长度。因此,顺序存储结构是把线性 表中每个元素a1, a2, a3, …, an依次存放到数 组下标为0, 1, 2,…, n1的位置上。
假设用数组data[MAXSIZE]存储线性 表 A =(a1, a2, a3, …, an) 其顺序存储结构如图2.1所示。
➢2.2.1 线性表的顺序存储结构 ➢2.2.2 顺序表的基本运算 ➢2.2.3 插入和删除运算的时间分析 ➢2.2.4 顺序表的优点和缺点
2.2.1 线性表的顺序存储结构
线性表的顺序存储方法是:将线性表的所有元素 按其逻辑顺序依次存放在内存中一组连续的存储 单元中,也就是将线性表的所有元素连续地存放 到计算机中相邻的内存单元中,以保证线性表元 素逻辑上的有序性。 顺序表的特点是:其逻辑关系相邻的两个结点在 物理位置上也相邻,结点的逻辑次序和物理次序 一致。
图2.1 顺序存储结构示意图
由于线性表中所有结点的数据类型是相同 的,因此每个结点占用的存储空间也是
相同的。假设每个结点占用d个存储单元,
若 线 性 表 中 第 一 个 结 点 a1 的 存 储 地 址 为 LOC(a1) , 那 么 结 点 ai 的 存 储 地 址 LOC(ai) 可以通过下面的公式计算得到:
【例2.3】学生成绩统计表也是一个线性表, 见表2.1。在线性表中每个学生的成绩是
一个数据元素,它由学号、姓名、数学、 外语、物理、总分这6个数据项组成。该 线性表的长度为5。
学号 1 2 3 4 5
姓名 李华 王放 张利 田勇 成惠
表 2.1 某班学生成绩统计表
第2章 线性表
特点:只能在一个方向上遍历其后的元素。 例:在上图的单链表中,指针p指向值为a2的结点。 head->data= ; head->next= ; head->next->data= 。
具有头结点的单链表
在链表的第一个结点之前附加一个与其它结点完全相同的 结点,称为头结点。 数据域——空的,或用来存放其它信息, 头结点 如链表的长度 指针域——指向链表的第一个结点 head 头结点 head ∧ (空表) a1 a2 an ∧
2.1.2 线性表的抽象数据类型
ListLocate(L,x) ListPrior(L,e) ListNext(L,e) // 查找值为x的元 //求元素e的前驱 //求元素e的后继
ListInsert(L,i,e) // 在第i个元素前插入元素e ListDelete(L,i) ListEmpty(L) ListClear(L) }ADT Linear_List // 删除第i个元素 // 判断表是否空 // 清空表中元素
1
2.1.3 线性表的相关操作
1.线性表的遍历 遍历——访问某种数据结构中的每一个元素,并且每个元 素只访问一次。 线性表的遍历:①空表?不遍历 ②非空表?表长访问每个元素
ListTraverse(L) { if(ListEmpty(L)) printf(“这是一个空表”); else for(i=1;i<=ListLength(L);i++) visit(ListGet(L,i)); } //访问线性表中的元素i //判断表是否为空 //遍历线性表中的元素
2.3 线性表的链式存储结构及其操作
2.3.1 线性链表与相关操作实现
2.3.2 双向链表与相关操作实现 2.3.3 循环链表与相关操作实现 2.3.4 链式存储结构的分析
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
线性表的顺序存储结构示意图
地址 b=LOC(a1) b+ L b +(i-1)L 内容
a1 a2 …… ai ai+1 ……
元素在表中的位序 L 1
2
i i+1 n 空闲区 下标起 点是1
b +(n-1)L b +(max-1)L
an
LOC ( ai ) = LOC( a1 ) + L *(i -1)
18
2.2.2 顺序表的实现(或操作)
数据结构的基本运算: 修改、插入、删除、查找、排序
1) 修改
通过数组的下标便可访问某个特定元素并修改之。 核心语句: V[i]=x;
显然,顺序表修改操作的时间效率是 O(1)
19
在线性表的第i个位置前插入一个元素的示意图如下:
1 2 3 4 5 6 7 8 12 13 21 24 1 2 3 4 5 12 13 21 24 25 28 30 42 77
2.1 线性表的定义
线性表的逻辑结构
(a1, a2, … ai-1,ai, ai+1 ,…, an)
数据元素
线性起点
ai的直接前趋 ai的直接后继 n=0时称为
线性终点
下标,是元素的 序号,表示元素 在表中的位置
空表
n为元素总
个数,即表 长。n≥0
9
例1 分析26 个英文字母组成的英文表是什么结构。 分析: 数据元素都是同类型(字母), 元素间关系是线性的。
分析:数据元素都是同类型(记录),元素间关系是线性的。 注意:同一线性表中的元素必定具有相同特性 !
10
试判断下列叙述的正误:
“同一数据逻辑结构中的所有数据元素都具有相同的特性”
是指数据元素所包含的数据项的个数都相等。
×
11
是指各元素具有相同的数据类型
2.2 线性表的顺序表示和实现
2.2.1 顺序表的表示
知识回顾
问 题
编写一个函数,实现以下功能:输入n个整数,求
最大值 计算该算法的时间复杂度
函 数
函数(方法)
实现某种功能的程序块
函数组成要素
函数名 参数个数、参数类型 返回值 类型 函数体(实现过程) return语句 返回值
数据结构内容
线性结构的定义:
若结构是非空有限集,则有且仅有一个开始结点和一个终端结点, 并且所有结点都最多只有一个直接前趋和一个直接后继。 可表示为: (a1 , a2 , ……, an)
O(1)
27
小结
线性结构 线性表 线性表的顺序表示 线性表的操作实现时间复杂度
作业
顺序表创建、显示操作C语言编程实现 顺序表插入、删除操作C语言编程实现并计算其时
间复杂度。(参考课件) 顺序表的查找(给定一个值,确定在顺序表中是否 存在该值,如果存在并输出所在位置)操作C语言 编程实现
n 1
删除效率:
1 n n 1 Edl qi (n i ) (n i ) n i 1 2 i 1
n
含义:对于顺序表,插入、删除操 作平均需要移动一半元素( n / 2 )
即插入、删除算法的平均 时间复杂度为 O(n)
想一想: 顺序表插入、删除算法的平均空间复杂度为多少? 因为没有占用辅助空间!
4
5 6 7
8
9
8
23
删除顺序表中某个指定的元素的示意图如下:
1 2 3 12 13 1 2 3 12 13
21
24 25 28 30 42 77
21
24 28 30 42 77
4
5 6 7
4
5 6ห้องสมุดไป่ตู้7
8
9
8
24
2.2.3 顺序表的运算效率分析
时间效率分析:
算法时间主要耗费在移动元素的操作上,因此
插入25
28
30 42 77
6
7 8 9
20
2)插入
在线性表的第i个位置前插入一个元素
实现步骤: • 将第n至第i 位的元素向后移动一个位置; • 将要插入的元素写到第i个位置; • 表长加1。 注意:事先应判断: 插入位置i 是否合法?表是否已满? 应当符合条件: 1≤i≤n+1 或 i=[1, n+1]
13
线性表顺序存储特点:
1. 2.
逻辑上相邻的数据元素,其物理上也相邻; 若已知表中首元素在存储器中的位置,则其他元 素存放位置亦可求出(利用数组V[n]的下标)。
设首元素a1的存放地址为LOC(a1)(称为首地址), 设每个元素占用存储空间(地址长度)为L字节, 则表中任一数据元素的存放地址为: LOC ( ai+1 ) = LOC( ai ) + L LOC ( ai ) = LOC( a1 ) + L *(i -1) 对上述公式的解释如图所示
( A, B, C, D, …… , Z)
例2 分析学生情况登记表是什么结构。
学号 U200713569 U200713611 U200713537 U200713564 U200713582 : 姓名 李春元 李煜墉 张祺轩 李姜辉 高 岩 : 性别 男 男 男 男 男 : 年龄 19 19 19 19 19 : 班级 通信工程200701班 通信工程200701班 通信工程200702班 通信工程200703班 通信工程200704班 :
15
例1 设有一维数组M,下标的范围是0到9,每个数组 元素用相邻的5个字节存储。存储器按字节编址,设存
储数组元素M[0]的第一个字节的地址是98,则M[3] 的第一个字节的地址是多少? 解:已知地址计算通式为: LOC(ai) = LOC(a1) + L *(i-1) 答案:113
但此题要注意下标起点是从0开始:
应当考虑在各种位置插入(共n+1种可能)的平均移动次数才合理。
25
推导: 假定在每个元素位置上插入 x 的可能性都一样(即概率 P 相 同),则应当这样来计算平均执行时间: 将所有位置的执行时间相加,然后取平均。
若在首结点前插入,需要移动的元素最多,后移次数为n; 若在a1后面插入,要后移n-1个元素,后移次数为n-1; …… 若在an-1后面插入,后移次数为1; 若在尾结点an之后插入,则后移次数为0;
2.2.2 顺序表的实现
2.2.3 顺序表的运算效率分析
12
2.2.1 顺序表的表示 线性表的顺序表示又称为顺序存储结构或顺序映像。
顺序存储定义: 把逻辑上相邻的数据元素存储在物理 上相邻的存储单元中的存储结构。 特点: 逻辑上相邻的元素,物理上也相邻
顺序存储方法: 用一组地址连续的存储单元依次存 储线性表的元素。 可以利用数组V[n]来实现 注意:在C语言中数组的下标是从0开始,即: V[n]的有效范围是从 V[0]~V[n-1]
计算时间复杂度的基本操作(最深层语句频度) T(n)= O (移动元素次数) 而移动元素的个数取决于插入或删除元素的位置。 讨论1:若在长度为 n 的线性表的第 i 位前 插入一个元素,则 向后移动元素的次数f(n)为: n–i+1 f(n) =
思考:若插入在尾结点之后,则根本无需移动(特别快); 若插入在首结点之前,则表中元素全部要后移(特别慢);
LOC( M[3] ) = 98 + 5 ×(4-1) =113
或用(3-0)
16
例2 用数组V来存放26个英文字母组成的线性表(a,b, c,…,z),写出在顺序结构上生成和显示该表的C语言程 序。
void build( char V[],int n)
建表操作
//字母线性表的生成,即
{ int i; V[0]='a'; for( i=1; i<=n-1; i++ )
for (j=n; j>=i; j--) { 核 // 元素后移一个位置 心 a[j+1]=a[ j ]; // 插入x 语 } 句: // 表长加1 a[ i ]=x; n++;
21
3)删除
删除线性表的第i个位置上的元素
实现步骤: 将第i+1 至第n 位的元素向前移动一个位置; 表长减1。 注意:事先需要判断,删除位置i 是否合法? 应当符合条件:1≤i≤n 或 i=[1, n]
所有可能的元素移动次数合计: 0+1+…+n = n(n+1)/2 共有多少种插入形式?——连头带尾有n+1种! 故插入时的平均移动次数为:n(n+1)/2÷(n+1)=n/2≈O(n)
26
同理可证:顺序表删除一元素的时间效率为: T(n)=(n-1)/2 ≈O(n)
1 n1 n (n i 1) 插入效率: Eis pi (n i 1) n 1 i 1 2 i 1
2.1 线性表的定义
线性表(Linear List) :是由n(n≧0)个数据元素 (结点)a1,a2, …an组成的有限序列。该序列中 的所有结点具有相同的数据类型。其中数据元素 的个数n称为线性表的长度。
当n=0时,称为空表。
当n>0时,将非空的线性表记作: (a1, a2,…an) a1称为线性表的第一个(首)结点,an称为线性表 的最后一个(尾)结点。
核心语句: for ( j=i+1; j<=n; j++ )
a[j-1]=a[j];
// 元素前移一个位置 // 表长减1
n--;
22
删除顺序表中某个指定的元素的示意图如下:
1 2 3 12 13 1 2 3 12 13
21
24 25 28 30 42 77
21