当前位置:文档之家› 数据结构第二章线性表.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++) {
线性表 14
线性表的顺序表示和实现
• LENGTH(L)--求解并返回线性表所含元素的个
数n。若线性表为空,则返回整数0。
int LENGTH(SqList *L){ if ((*L).last==-1) return 0; else
return((*L).last+1); }∥LENGTH
时间复杂度:O(1)
数据结构
2 线性表
线性表
1
2.1 线性表的基本概念
• 数据元素之间具有的逻辑关系为线性关系的数据元素集合称为 线性表。
• 一般表示为: A=( a1,a2,a3,... ...,an ) • n个元素的有限序列 • 元素的个数n为线性表的长度,如果n=0,则为空表。 • 线性关系如下:
(1)当1<i<n时,ai的直接前驱为ai-1,ai的直接后继为ai+1。 (2)除了第一个元素与最后一个元素,序列中任何一个元素有且仅有 一个直接前驱元素,有且仅有一个直接后继元素。
}SqList;
0 "aaa" 1 "bbb" 2 "abc"
… last n-1 "an"

maxsize-1
线性表 20
int LOCATE(SqList *L,datatype x){
int i=0;
while( i<(*L).last &&
strcmp((x*,L()*.Ld)a.tdaa[tia][!i=]x) )
int INSERT(SqList *L,datatype x,int i){
int j;
∥表溢出
if(((*L).last) >= maxsize-1){
printf("overflow");return -1;} else ∥非法位置
if(i < 1 || i >(*L).last + 2){
i++;
if( i==(*L).last && (*L).data[i]!=x )
return(-1);
else return(i+1); } ∥LOCATE
时间复杂度:O(n)
线性表 17
线性表的顺序表示和实现
• compare的实现? – 假设typedef char *datatype; – 即datatype是一个C风格的字符串 – 显然不能直接用!=来比较 – compare所指向的比较函数如下: – 调用:LOCATE(L,"abc");
return(1); } ∥INSERT
线性表 24
线性表的顺序表示和实现
• 插入操作的算法复杂度
− 很显然,插入操作的复杂度由需要移动的元素的个数决定 − 而需要移动元素的个数由插入位置决定
• i = n+1时,需要移动0个 • i = n时:1个 • ... • i = 1时:n个 • 即:需要移动的元素个数 = n-i+1
}
name[0] name[1] name[2]
Follow me Basic
Great wall
线性表 19
线性表的顺序表示和实现
#define maxsize 1024 typedef char* datatype;
typedef struct{ datatype data[maxsize]; ∥定义线性表 int last; ∥终端结点的位置
线性表 10
a1 a2 a3
……
an
若假设每个数据元素占用k个存储单元,并且已知 第一个元素的存储位置LOC(a1),则有
LOC(ai)=LOC(a1)+(i-1)*k
例:LOC(a1)=100 k=4 求LOC(a5)=? a1 a2 a3 a4 a5 … … an
100 104 108 112 116
通过上面的例子可以看出: • 逻辑结构是数据组织的某种"本质性"的东西:
(1)逻辑结构与数据元素本身的形式、内容无关。 (2)逻辑结构与数据元素的相对位置无关。 (3)逻辑结构与所含数据元素的个数无关。 • 算法的设计取决于选定的逻辑结构,而算法的实现依赖于 采用的存储结构。
线性表
9
2.2 线性表的顺序存储结构
(a1,a2,…,ai-1, ai,ai+1,…,an-1,an)
n个数据元素
转换成长度为n+1的线性表 (a1,a2,…,ai-1,item,ai,…,an-1,an)
n+1个数据元素
线性表 22
n-i+1个元素
( a1,a2,…,ai-1,ai,ai+1,.. ...,an-1,an )
item
线性表 25
线性表的顺序表示和实现
• 最好情况 – T(n) = O(1)
• 最差情况 – T(n) = O(n)
• 平均情况呢? – 一共有1,2,...,n+1,n+1个可能的插入位置,在 第i个位置上插入的概率是1/(n+1) – 所以平均需要移动元素的个数

1
n 1
(n 1 i)
printf("ERROR"); return -1;}
else {
for(j=(*L).last;j>=i-1;j--)
(*L).data[j+1] =(*L).data[j];
∥写进待插入的元素x
(*L).data[i-1] = x; (*L).last = (*L).last+1; ∥表长加1 } ∥else
x=GET(B,i);
∥依次取线性表B中的元素,存放在x中
k=LOCATE(A,x); ∥在线性表A中查找x
if(k!=-1) DELETE(A,k);∥若在表A中找到,将其删除 }∥if }∥delete
线性表
6
算法举例2.3 公共元素表
编写将线性表A和B中公共元素生成线性表C的算法。
1 3 57 9
void ListTraverse(SqList *L){
∥遍历线性表
int i,n=Length(L); if(!n) printf("空表\n"); else
for(i=1;i<=n;i++) printf("%d ",GET(L,i)); } ∥ListTraverse
线性表
4
算法举例2.2 删除元素
int MyComp(datatype lhs, datatype rhs){ return strcmp(lhs, rhs); } ∥MyComp
线性表 18
指针数组
定义形式:类型标示符 *数组名[常量表达式];
例:int *p[4];
main( ){ int i; char *name[ ]={"follow me",“Basic","Great wall"}; for (i=0; i<3; i++) printf("%s\n", name[i]);
#define maxsize 1024 typedef int datatype;
typedef struct{ datatype data[maxsize];
∥定义线性表
int last;
∥终端结点的位置
}SqList;
下标 内存状态
last
0 a1 1 a2 2 a3
… n-1 an


maxsize-1
12346
13
【算法思路】
先初始化线性表C,然后依次检查线性表A中的每个元素, 看它是否在线性表B中;若在线性表B中,则将其插入到线性 表C中。
线性表
7
相关主题