数据结构 课件 第二章
合集下载
《数据结构》课件第二章
线性表的基本操作(逻辑)
➢ 构造一个空表L ➢ 获取L的长度(即元素个数) ➢ 访问L中第i个数据元素的值 ➢ 访问L中第i个数据元素的前驱/后继的值 ➢ 在L中第i个元素之前插入新的元素e ➢ 删除L的第i个数据元素
➢ 注意在插入或者删除之后,线性表的长度应 能随之改变
一 顺序存储
➢ 线性表的顺序表示:用一组地址连续的存储单 元依次存储线性表的数据元素。
否
将Temp_b插入到 LC的第k个位置上
Temp_a ≤ Temp_b
是 将Temp_a插入到 LC的第k个位置上
否 i ≤ LA.len 否
j← j + 1
i← i + 1
j ≤ LB.len
Temp_a = Temp_b
是
否
否
j← j + 1
k← k + 1
结束
是
将LA表的第i个元 素插入到LC表的
插入操作的时间复杂度 O(n/2) 链表中的插入、删除操作没有上溢的情况, 并且节省内存资源
思考:若现已知道指向某元素节点的指针 p,希望能在该节点之前插入元素x,该如 何操作?其算法时间复杂度是多少?
3) 单链表的删除
p
删除第i个元素,由e返回值 删除b
a
Hale Waihona Puke bc … 1) 寻找第i-1个结点
2) 保留结点b的地址
9 SHI 5
0
1
1 ZHAO 2
2 QIAN 3
3 SUN 4
4 LI
9
5 ZHOU 6
6 WU 8
7 ZHENG 8
8 WANG 0
9 SHI 5
i=s[i].cur 指针后移
数据结构(严蔚敏)课件 第2章 线性表C(链表的操作)
//插入非空表的剩余段 //释放Lb的头结点 ?:是条件运算符(为真则取第1项,见P10条件赋值)
22
注:Lc用的是La的头指针
思
考:
1、不用Lc,直接把La表插到Lb表中;或者 把Lb表插到La表中,怎么修改?
2、重复的数据元素不需要插入,怎么修改?
23
一个带头结点的线性链表类型定义如下 (用类C语言,见P37):
29
续例2:一元多项式的计算 (参见教材P39 – 43) 后续内容
12
(2) 单链表的修改(或读取)
(3) 单链表的插入(P29)
在链表中插入一个元素X 的示意图如下: p a p
b
插 入 X
a
b
p->next
s
X
s->next
链表插入的核心语句: Step 1:s->next=p->next; Step 2:p->next=s ; 思考:Step1和2能互换么?
//链表中元素个数(长度)
表结构
前面的归并算法可改写为P39算法2.21
24
例2:一元多项式的计算 (参见教材P39 – 43) 讨论:
1. 一元多项式的数学通式? 2. 用抽象数据类型如何描述它的定义?
3. 用C语言如何描述它的定义?
4. 如何编程实现两个一元多项式相加?
25
1. 一元多项式的数学通式?
新手特别容易忘记!!
8
void display()
/*字母链表的输出*/
{p=head; sum=0; while (p) //当指针不空时循环(仅限于无头结点的情况) {printf("%c",p->data); p=p->next; //让指针不断“顺藤摸瓜” } sum++; }
22
注:Lc用的是La的头指针
思
考:
1、不用Lc,直接把La表插到Lb表中;或者 把Lb表插到La表中,怎么修改?
2、重复的数据元素不需要插入,怎么修改?
23
一个带头结点的线性链表类型定义如下 (用类C语言,见P37):
29
续例2:一元多项式的计算 (参见教材P39 – 43) 后续内容
12
(2) 单链表的修改(或读取)
(3) 单链表的插入(P29)
在链表中插入一个元素X 的示意图如下: p a p
b
插 入 X
a
b
p->next
s
X
s->next
链表插入的核心语句: Step 1:s->next=p->next; Step 2:p->next=s ; 思考:Step1和2能互换么?
//链表中元素个数(长度)
表结构
前面的归并算法可改写为P39算法2.21
24
例2:一元多项式的计算 (参见教材P39 – 43) 讨论:
1. 一元多项式的数学通式? 2. 用抽象数据类型如何描述它的定义?
3. 用C语言如何描述它的定义?
4. 如何编程实现两个一元多项式相加?
25
1. 一元多项式的数学通式?
新手特别容易忘记!!
8
void display()
/*字母链表的输出*/
{p=head; sum=0; while (p) //当指针不空时循环(仅限于无头结点的情况) {printf("%c",p->data); p=p->next; //让指针不断“顺藤摸瓜” } sum++; }
数据结构课件第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值不合法”);
《数据结构》课程课件第二章线性表
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、其它操作 复制、分解、合并、分类等
数据结构 (2).ppt
(*L).data[i-1]
LOCATE(L,x)
INSERT(L,x,i)
DELETE(L,i)
2020/5/6
数据结构
22
顺序表的特点: 用物理位置上的邻接关系表示结点间的逻辑关系
顺序表的优点: (1)无须增加额外的存储空间表示结点间的逻辑关系。
(2)可以方便地随机存取表中任一结点。
顺序表的缺点: (1)插入和删除运算不方便,通常须移动大量结点,效率 较低。 (2)难以进行连续的存储空间的预分配,尤其是当表变化 较大时。
Head a
r
b
c^
sr d ^
•不带头结点的尾插法:插入时,第一个结点的处理与其 它结点的处理有区别。
结束时,空表和非空表的处理有区别。
2020/5/6
数据结构
29
Linklist *CREATLISTR( )
{ char ch;
linklist *head,*s,*r;
head=NULL; r=NULL; ch=getchar( );
int last;
0
a1
1
a2
. . .
(*L).last
an
} sequenlist;
Maxsize-1
last
说明: (1).datatype是表中的数据类型,依具体情况而定 (2).向量下标可以看作表中结点的相对地址
(3). 顺序表的长度为last+1
(4).结点的引用:定义一个顺序表:sequenlist *L;
它位置上的操作相一致。
2)空表和非空表的处理相一致。
2020/5/6
数据结构
31
2.3.2 单链表上的基本运算(实现)
数据结构课件-第二章
1初始化单链表 Void InitList(LinkList *head) {/* 初始化单链表 */ head=(LinkList)malloc(Sizeof(ListNode)) /*申请头结点空间,并使头指针head指向头结点 */ head->next=NULL; /* 置链尾标记NULL */ }
2.4线性表的链式存储结构
链式存储结构用一组任意的存储单元依次存储 线性表里元素,这组存储单元可以是连续的, 也可以是不连续的,甚至是零散分布在内存的 任何位置上。
为反映出各元素在线性表中的逻辑关系,对每 个数据元素来说,除了存储其本身的信息之外 ,还需存储一个指示其直接后继的信息(即直 接后继的存储位置)。这两部分信息组成一个 数据元素的存储映象,称为结点(Node)。
例如,图2-4-2所示为线性表(dog,pig,cat,fox,hen,bat ,bee,bird)的单链表存储结构,整个链表的存取需从头指针开始 进行,依次顺着每个结点的指针域next找到线性表的各个元素,直 至next域为空为止。
通常我们用箭头表示链域中的指针:
typedef struct Node {ElemType data; /*数据域*/ struct Node *next; /*指针域*/ }ListNode,*LinkList;
2.3.1 线性表的顺序存储
线性表的顺序存储是指用一组地址连续的存储单元依 次存储线性表中的各个元素,使得线性表中在逻辑结 构上相邻的数据元素存储在相邻的存储单元中 。
假设线性表中有n个数据元素,每个数据元素占K个 存储单元,第一个元素a1的存储地址用LOC(a1)表示 ,第i个数据元素ai的地址用LOC(ai)表示,则: 第i个数据元素的地址为: LOC(ai)=LOC(a1)+(i-1)×K (1≤i≤n)
数据结构课件第2章
SqStack S; ElemType e;
InitStack_Sq(S, 10, 5); // 栈S的初始容量为10
while(N!=0) {
Push_Sq(S, N%8); // 将N除以8的余数入栈
N /= 8;
// N取值为其除以8的商
}
while(FALSE==StackEmpty_Sq(S)) {
括号匹配
int i = 0; ElemType e; SqStack S; InitStack_Sq(S, n, 5);
Status Matching(char *exp, int n)
while(i<n) { switch(exp[i]) {
当读入完所有括号时,检查栈:
case '(': case '[': Push_Sq(S, exp[i]); i++;
本章主要内容
2.1 典型线性数据结构 2.2 顺序栈 2.3 循环队列 2.4 顺序表 2.5 链栈与链队列 2.6 线性表的链式表示与实现 2.7 线性表两种存储结构的比较
2.1典型的线性结构
栈(stack):只允许在序列末端进行操作的线性结 构;
队列(queue): 只允许在序列两端进行操作的线 性结构;
样式: 数据 指针
或 指针 数据 指针
数据域:存储元素数 值数据
指针域:存储直接后继或者直接前 驱的存储位置
1.7.3节的链表存储结构
链式存储
线性结构的链式存储表示
a1
a2
…
an ∧
栈、队列和线性表的链式存储表示
链栈 链队列 单链表、双向链表、循环链表、双向循环链表
2.2 栈的顺序表示和实现
数据结构(第二章)
建立顺序表
void creat_sqlist(Sqlist L) { int i,n; cout<<"n=?; cin>>n; L.length=n; for (i=0; i<n; i++) cin>>L.a[i]; }
initlist(Sl);
输出顺序表
void outputl(Sqlist L) { int i; cout<<"List length" <<L.length<<endl; for (i=0; i<L.length; i++) { cout<<L.a[i]<<" "; if ((i+1)%10==0) cout<<endl; } cout<<endl; }
4. 合并:两表分别非递减有序(递增或等值),合并后 仍然非递减有序。
void merge_list(Sqlist a, Sqlist b, Sqlist &c) { int i,j,k; i=j=k=0; c.length=a.length+b.length; while (i<=a.length-1 && j<=b.length-1) { if (a.a[i]<=b.a[j]) {c.a[k]=a.a[i]; i++; k++;} else {c.a[k]=b.a[j]; j++; k++;} } while (i<=a.length-1) { c.a[k]=a.a[i]; i++; k++; } while (j<=b.length-1) { c.a[k]=b.a[j]; j++; k++; } }
数据结构课件CHAPTER2
a1
a2
a3
a4
a5
a6
直接前驱和直接后继描述了结点之间的逻辑关系 (即邻接关系)
Department of Computer Science & Technology, Nanjing university fall
线性表的抽象基类 template <class T, class E> class LinearList { public: LinearList(); //构造函数 //析构函数 〜~LinearList(); virtual int Size() const = 0; //求表最大大体积 virtual int Length() const = 0; //求表⻓长度 virtual int Search(T x) const = 0; //搜索 virtual int Locate(int i) const = 0; //定位 virtual E* getData(int i) const = 0; //取值 virtual void setData(int i, E x) = 0; //赋值
Nanjing university
fall
删除的主要思想: (1) 在顺序表中查找x,如果x在表中不存在,则 不能删除;
Data Structures
(2)如果x在表中存在,设x在顺序表中的位置 为i; (3) 将顺序表的最后位置减1; (4)把顺序表中原来第i+1至第n-1个表项依次向 前移动一个表项位置
Department of Computer Science & Technology, Nanjing university fall
Data Structures
数据结构课件C++版第二章
线性结构的特点
a1
a2
a3
a4
a5
a6
存在一个唯一被称作“第一个”的数据元素; ② 存在一个唯一被称作“最后一个”的数据元素; ③ 除第一个数据元素外,其他元素均有且仅有一个 直接前驱,第一个元素没有前驱; ④ 除最后一个数据元素外,其他元素均有且仅有一 个直接后继,最后一个元素没tructure--Ch2 Linear List mayan
2013-7-14 Data Structure--Ch2 Linear List mayan
2.1 线性表(Linear List)
2.1.4线性表的存储表示
① ②
线性表的存储表示 顺序存储方式 链表存储方式
2013-7-14
Data Structure--Ch2 Linear List
mayan
2.2 顺序表(Sequential List) 2.2.1 定义及特点
定义 线性表的顺序存储方式(顺序表)指的是用一 组地址连续的存储单元依次存储线性表的数据元 素。即它利用元素在物理位置上的邻接关系来表 示表中元素间的逻辑关系。通常用数组来实现。
0 1 ...
...
下标位置 存储状态 存储位置
在表中顺序搜索与给定值 x 匹配的表项,找到 则函数返回该表项是第几个元素,否则函数返回0
2013-7-14 Data Structure--Ch2 Linear List mayan
2.2 顺序表(Sequential List) 2.2.2 类定义及其操作 --表项的插入算法
template <class T > 表项位置i 1 2 bool SeqList<T>::Insert (int i, T& x) { 值 a b last 0 if (last == maxSize-1) return false; //表满 1 i=3 if (i < 0 || i > last+1) return false; //参数i不合理 表项位置 1 for (int j = last; j >= i; j--) //依次后移2 3 值 a b c 新值 a b c data[j+1] = data[j]; 下标 0 1 2 data[i] = x; //插入(第 i 表项在data[i-1]处) last++; return true; //插入成功 }
数据结构课件第2章线性表A
22
2.2 线性表的顺序表示和实现
2.2.1 顺序表的表示 2.2.2 顺序表的实现 2.2.3 顺序表的运算效率分析 本节小结 作 业
23
2.2.1 顺序表的表示
线性表的顺序表示又称为顺序存储结构 顺序映像。 顺序存储结构或 线性表的顺序表示又称为顺序存储结构或顺序映像。 顺序存储定义: 顺序存储定义: 把逻辑上相邻的数据元素存储在物 理上相邻的存储单元中的存储结构。 理上相邻的存储单元中的存储结构。 简言之,逻辑上相邻, 简言之,逻辑上相邻,物理上也相邻 顺序存储方法: 顺序存储方法: 用一组地址连续 地址连续的存储单元依次 用一组 地址连续 的存储单元依次 存储线性表的元素,可通过数组V[n]来实现 数组V[n]来实现。 存储线性表的元素,可通过数组V[n]来实现。
9
形式化定义: 形式化定义: Linearlist = (D, R) 其中: 其中:
D = {ai | ai ∈ D0 , i = 0,1,L , n − 1, n > 0} R = {< ai −1 , ai >| ai −1 , ai ∈ D0 , i = 1,2, L , n − 1}
D0为某个数据对象的集合 N为线性表长度 为线性表长度
数据元素都是记录; 数据元素都是记录
元素间关系是线性
13
同一线性表中的元素必定具有相同特性
例3、学生健康情况登记表如下: 姓 名 王小林 陈 红 刘建平 张立立 …….. 学 号 790631 790632 790633 790634 …….. 性 别 年龄 男 女 男 男 ……. 18 20 21 17 ……. 健康情况 健康 一般 健康 神经衰弱 …….
10
线性表的主要操作
初始化 求长度 取元行如下基本运算: 对线性表可进行如下基本运算:
2.2 线性表的顺序表示和实现
2.2.1 顺序表的表示 2.2.2 顺序表的实现 2.2.3 顺序表的运算效率分析 本节小结 作 业
23
2.2.1 顺序表的表示
线性表的顺序表示又称为顺序存储结构 顺序映像。 顺序存储结构或 线性表的顺序表示又称为顺序存储结构或顺序映像。 顺序存储定义: 顺序存储定义: 把逻辑上相邻的数据元素存储在物 理上相邻的存储单元中的存储结构。 理上相邻的存储单元中的存储结构。 简言之,逻辑上相邻, 简言之,逻辑上相邻,物理上也相邻 顺序存储方法: 顺序存储方法: 用一组地址连续 地址连续的存储单元依次 用一组 地址连续 的存储单元依次 存储线性表的元素,可通过数组V[n]来实现 数组V[n]来实现。 存储线性表的元素,可通过数组V[n]来实现。
9
形式化定义: 形式化定义: Linearlist = (D, R) 其中: 其中:
D = {ai | ai ∈ D0 , i = 0,1,L , n − 1, n > 0} R = {< ai −1 , ai >| ai −1 , ai ∈ D0 , i = 1,2, L , n − 1}
D0为某个数据对象的集合 N为线性表长度 为线性表长度
数据元素都是记录; 数据元素都是记录
元素间关系是线性
13
同一线性表中的元素必定具有相同特性
例3、学生健康情况登记表如下: 姓 名 王小林 陈 红 刘建平 张立立 …….. 学 号 790631 790632 790633 790634 …….. 性 别 年龄 男 女 男 男 ……. 18 20 21 17 ……. 健康情况 健康 一般 健康 神经衰弱 …….
10
线性表的主要操作
初始化 求长度 取元行如下基本运算: 对线性表可进行如下基本运算:
数据结构课件ppt第二章
答:由于顺序存储结构一旦确定了起始位置, 线性表中的任何一个元素都可以进行随机存 取,即存取速度较高;并且,由于线性表的 总数基本稳定,且很少进行插入和删除,故 这一特点恰好避开了顺序存储结构的缺点。 因此,应选用顺序存储结构。
3. 在单链表和双向链表中,能否从当前结点 出发访问到任一结点?
• 答:在单链表中只能由当前结点访问其后 继的任一结点,但因其没有指向前驱的指 针而无法访问其前驱结点。在双向链表中, 由于当前结点既有指向后继的指针,又有 指向前驱的指针,所以在双向链表中可以 由当前结点出发访问表中的任何一个结点。
data 0
1
a2
2
a1
3
4
a3
cursor 2 4 1
0
data 0
1
a2
2
a1
3
a4
4
a3
cursor 2 3 1
4 0
…
…
…
…
maxsize-1
maxsize-1
静态链表的C语言描述
//线性表的静态链表存储结构 # define MAXSIZE 100 //链表的最大长度 typedef struct {
D. 循环链表
答案:C,D
A,C,D
写出带头结点的双向循环链表L为空表的 条件:
空表 L
答案:(L==L->next)&&(L==L->prior)
判断题
1. 在具有头结点的链式存储结构中,头指针 指向链表中的数据结点。( )
2. 顺序存储的线性表可以随机存取。( ) 3. 在单链表中,要访问某个结点,只要知道
} DuLNode, *DuLinkList;
2. 循环链表
3. 在单链表和双向链表中,能否从当前结点 出发访问到任一结点?
• 答:在单链表中只能由当前结点访问其后 继的任一结点,但因其没有指向前驱的指 针而无法访问其前驱结点。在双向链表中, 由于当前结点既有指向后继的指针,又有 指向前驱的指针,所以在双向链表中可以 由当前结点出发访问表中的任何一个结点。
data 0
1
a2
2
a1
3
4
a3
cursor 2 4 1
0
data 0
1
a2
2
a1
3
a4
4
a3
cursor 2 3 1
4 0
…
…
…
…
maxsize-1
maxsize-1
静态链表的C语言描述
//线性表的静态链表存储结构 # define MAXSIZE 100 //链表的最大长度 typedef struct {
D. 循环链表
答案:C,D
A,C,D
写出带头结点的双向循环链表L为空表的 条件:
空表 L
答案:(L==L->next)&&(L==L->prior)
判断题
1. 在具有头结点的链式存储结构中,头指针 指向链表中的数据结点。( )
2. 顺序存储的线性表可以随机存取。( ) 3. 在单链表中,要访问某个结点,只要知道
} DuLNode, *DuLinkList;
2. 循环链表
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
2.2 线性表的顺序表示和实现
时间复杂度分析 查找线性表L中与e相同的结点ai,其 时间主要耗费在e与表中结点的比较操作 上,因此,可用比较次数来估计算法的时 间复杂度。
2.2 线性表的顺序表示和实现
时间复杂度分析 设在线性表L中与e相同的第i个结点的概率 为Pi,不失一般性,设各个位置是等概率,则 Pi=1/n,而比较次数为i。 则总的平均比较次数: Elocate=∑pi*i (1≦i≦n) ∴ Elocate=(n+1)/2 。 即在顺序表上做定位运算,平均要与表中 一半的数据元素进行比较。当表长n较大时,算 法的效率相当低。因此算法的平均时间复杂度 为O(n)。
LOC(ai+1)=LOC(ai)+l 线性表的第i个数据元素ai的存储位置为:
LOC(ai)=LOC(a1)+(i-1)*l
2.2 线性表的顺序表示和实现
在高级语言(如C语言)环境下,数组具有随机存 取的特性,因此,借助数组来描述顺序表。除 了用数组来存储线性表的元素之外,顺序表还 应该有表示线性表的长度属性,所以用结构类 型来定义顺序表类型。 #define OK 1 #define ERROR -1
2.3 线性表的链式表示和实现
顺序存储结构的优点:
无需为表示数据元素之间的关系而额外增加 存储空间 可以随机存取表中任一数据元素 插入或删除运算必须移动大量(几乎一半) 数据元素,效率较低。 必须预先分配存储空间,造成空间利用率低。 要扩充表的容量必须重新分配内存。
顺序存储结构的缺点:
2.1 线性表的类型定义
线性表(Linear List) :是由n(n≧0)个数据元 素(结点)a1,a2, …an组成的有限序列。该序 列中的所有结点具有相同的数据类型。其中数据 元素的个数n称为线性表的长度。
当n=0时,称为空表。 当n>0时,将非空的线性表记作: (a1,a2,…an) a1称为线性表的第一个(首)结点。 an称为线性表的最后一个(尾)结点。
Status Init_SqList( SqList *L )
2.2 线性表的顺序表示和实现
顺序线性表的插入
在线性表 L= (a1,…a i-1,ai, ai+1,…,an) 中的 第i(1≦i≦n)个位置上插入一个新结点e,使其成为线 性表: L=(a1,…a i-1,e,ai,ai+1,…,an)
2.1 线性表的类型定义
ai是第i个数据元素,称i为数据元素ai在线性 表中的位序。 a1,a2,…ai-1都是ai(2≦i≦n)的前驱,其 中ai-1是ai的直接前驱; ai+1,ai+2,…an都是ai(1≦i ≦n-1)的后 继,其中ai+1是ai的直接后继。
线性表中的数据元素ai所代表的具体含义 随具体应用的不同而不同,在线性表的定 义中,只不过是一个抽象的表示符号。
2.2 线性表的顺序表示和实现
时间复杂度分析 删除线性表L中的第i个元素,其时间 主要耗费在表中结点的移动操作上,因此, 可用结点的移动来估计算法的时间复杂度。
2.2 线性表的顺序表示和实现
时间复杂度分析 设在线性表L中删除第i个元素的概率为Pi, 不失一般性,设删除各个位置是等概率,则 Pi=1/n,而删除时移动结点的次数为n-i。 则总的平均移动次数: Edelete=∑pi*(n-i) (1≦i≦n) ∴ Edelete=(n-1)/2 。 即在顺序表上做删除运算,平均要移动表 上一半结点。当表长n较大时,算法的效率相当 低。因此算法的平均时间复杂度为O(n)。
2.2 线性表的顺序表示和实现
顺序线性表初始化
{ L->elem_array=( ElemType * )malloc(MAX_SIZE*sizeof( ElemType ) ) ; if ( !L -> elem_array ) return ERROR ; else { L->length= 0 ; } return OK ; }
2.2 线性表的顺序表示和实现
算法描述
int Locate_SqList (Sqlist *L, ElemType e) { int i =1;
while((i<=L->length) && (L-> Elem_array[i-1]!=e))
i++; if (i>L->length ) return 0 ; else return i ; }
… } ADT List
2.2 线性表的顺序表示和实现
线性表的顺序表示指的是用一组地址连续 的存储单元依次存储线性表的数据元素。 顺序存储的线性表的特点:
线性表的逻辑顺序与物理顺序一致; 数据元素之间的关系是以元素在计算机内 “物理位置相邻”来体现。
2.2 线性表的顺序表示和实现
设有非空的线性表:(a1,a2,…an) 。 顺序存储如图所示
2.1 线性表的类型定义
线性表中的结点可以是记录型元素,每个元素含 有多个数据项 ,每个项称为结点的一个域 。每 个元素有一个可以唯一标识每个结点的数据项组, 称为关键字。
例4 : 某校2001级同学的基本情况:{(„2001414101‟, ‘王小林’,‘男’,06/24/1983), („2001414102‟,‘刘建平’,‘男’, 08/12/1984) …, („2001414102‟,‘陈红’, ‘女’,08/12/1984) }
2.2 线性表的顺序表示和实现
#define MAX_SIZE 100 typedef int Status ; typedef int ElemType ; typedef struct sqlist { ElemType Elem_array[MAX_SIZE] ; int length ; } SqList ;
2.2 线性表的顺序表示和实现
顺序线性表的定位
在线性表 L=(a1,…a i-1,ai, ai+1,…,an) 中 查找与e相同的结点ai(1≦i≦n),若找到,返回其在L 中的位序i,否则返回0;
实现步骤
(1) 将e与线性表L中的第1个至第n个结点依次比较, 若相等,返回i。 (2) 若e与线性表L中的所有结点都不相等,返回0。
2.1 线性表的类型定义
线性表是一种相当灵活的数据结构,其长 度可根据需要增长或缩短。 对线性表的数据元素可以访问、插入和删 除。
2.1 线性表的类型定义
抽象数据类型线性表的定义 ADT List{
数据对象:D = { ai | ai∈ElemSet, i=1,2,…,n, n≧0 } 数据关系:R = {<ai-1, ai> | ai-1, ai∈D, i=2,3,…,n } 基本操作: InitList( &L ) 操作结果:构造一个空的线性表L;
总的平均移动次数: Einsert=∑pi*(n-i+1) (1≦i≦n) ∴ Einsert=n/2 。
即在顺序表上做插入运算,平均要移动表上一半结 点。当表长n较大时,算法的效率相当低。因此算法的 平均时间复杂度为O(n)。
2.2 线性表的顺序表示和实现
顺序线性表的删除
在线性表 L=(a1,…a i-1,ai, ai+1,…,an) 中 删除结点ai(1≦i≦n),使其成为线性表:
第2章 线性表
数据结构
2011 2010年
前言
线性结构是最常用、最简单的一种数据结构。 而线性表是一种典型的线性结构。其基本特点 是:线性表中的数据元素是有序且是有限的。 在这种结构中:
存在一个唯一的被称为“第一个”的数据元素; 存在一个唯一的被称为“最后一个”的数据元素; 除第一个元素外,每个元素均有唯一一个直接前驱; 除最后一个元素外,每个元素均有唯一一个直接后 继。
}
2.2 线性表的顺序表示和实现
时间复杂度分析
在线性表L中的第i个元素之前插入新结点, 其时间主要耗费在表中结点的移动操作上,因 此,可用结点的移动来估计算法的时间复杂度。
2.2 线性表的顺序表示和实现
时间复杂度分析
设在线性表L中的第i个元素之前插入结点的概率为 Pi,不失一般性,设各个位置插入是等概率,则 Pi=1/(n+1),而插入时移动结点的次数为n-i+1。
实现步骤
(1) 将线性表L中的第i个至第n个结点后移一个位置。 (2) 将结点e插入到结点ai-1之后。 (3) 线性表长度加1。
2.2 线性表的顺序表示和实现
算法描述
Status Insert_SqList (Sqlist *L,int i , ElemType e) { int j ; if ( i<1||i>L->length+1) return ERROR ; if (L->length>=MAX_SIZE) { printf(“线性表溢出!\n”); return ERROR ; }
2.2 线性表的顺序表示和实现
for ( j=L->length–1; j>=i-1; --j ) L->Elem_array[j+1]=L>Elem_array[j];
/* i-1位置以后的所有结点后移 */
L->Elem_array[i-1]=e;结点 来自//* 在i-1位置插入
L->length++ ; return OK ;
2.1 线性表的类型定义
ListEmpty( L ) 初始条件:线性表L已存在; 操作结果:若L为空表,则返回TRUE,否则返回FALSE; …. GetElem( L, i, &e ) 初始条件:线性表L已存在,1≦i≦ListLength(L); 操作结果:用e返回L中第i个数据元素的值; ListInsert (&L, i, e ) 初始条件:线性表L已存在,1≦i≦ListLength(L) ; 操作结果:在线性表L中的第i个位置插入元素e;