第二章 线性表
合集下载
第二章线性表

//最后元素在数组中的位置(下标值)
} 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年各种型 号的计算机拥有量的变化情况:
线性表

举例:
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的线性表。
上述两例中的每一个数据元素都是不可分割的, 在一些复杂的线性表中,每一个数据元素又可 以由若干个数据项组成。
数据结构课件第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章 线性表

特点:只能在一个方向上遍历其后的元素。 例:在上图的单链表中,指针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 链式存储结构的分析
第2章 线性表 (数据结构教程PPT课件)

3.在数组a中检索(查找)值为X的数据元素
int locate (int a[ ],int n, int x) { int i; i=0; while((i<=n-1)&&(a[i]!=x)) i++; if(i<=n-1) return (i); /*返回的是存储位置*/ else return (0);} }
(2)按值查找即定位 Locate_LinkList(L,x) Lnode * Locate_LinkList( LinkList L, datatype x) /*在单链表L中查找值为x的结点,找到后 返回其指针,否则返回空*/ { Lnode * p=L->next; while ( p!=NULL && p->data != x) p=p->next; return p; }
2.2.2 典型操作的算法实现
1. 初始化线性表L
SeqList *init_SeqList( )
{ SeqList *L; L=malloc(sizeof(SeqList)); L->last=-1; return L; }
2.在数组a第i个数据元素之(ai-1)前插入数据 元素X insert (int a[ ],int n,int i, int x) { int j; for(j=n-1;j>=i-1;j--) a[j+1]=a[j]; /* 结点移动 */ a[i-1]=x; /*新元素插入*/ n++; /*修改长度*/ }
4.删除数组a第i个数据元素(ai-1) delete (int a[ ],int n,int i) { int j; for(j=i;j<=n;j++) a[j-1]=a[j]; /* 结点移动 */ n--; /*修改长度*/ }
线性表ppt
由于C语言函数的参数仅能向被调函数传值,这个值在返 回时也不会改变,因此在上面的算法中,采用指针变量v做形 参,虽然从被调函数返回时指针v值不变,但是v地址中所代表 的结构体的内容发生了变化。这就是所谓的传址调用。
假设在主函数中已经建立了线性表结构体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章 线 性 表
在上述的操作运算中,最基本最重要的是插入、删除。 线性表的其他复杂操作和运算还有:对有序表的插入和删除; 按某种要求重排线性表中各元素的顺序;按某个特定值查找 线性表中的元素;两个线性表的合并等。
假设在主函数中已经建立了线性表结构体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章 线 性 表
在上述的操作运算中,最基本最重要的是插入、删除。 线性表的其他复杂操作和运算还有:对有序表的插入和删除; 按某种要求重排线性表中各元素的顺序;按某个特定值查找 线性表中的元素;两个线性表的合并等。
《第二章线性表》PPT课件
en = e; // en为最后一次La插入的值 } // La中不存在和 e 相同的数据元素,则插入
例 2-3
归并两个"其数据元素按值非递减有序 排列"的有序表 LA 和 LB,求得有序表 LC 也具有同样特性.
设 La = <a1, …, ai, …, an>, Lb = <b1, …, bj, …,
ListInsert<Lc, ++k, ai>; ++i; } else { // 将 bj 插入到 Lc 中
ListInsert<Lc, ++k, bj>; ++j; }
void MergeList<List La, List Lb, List &Lc> { // 本算法将非递减的有序表 La 和 Lb 归并为 LcInitList<Lc>; // 构造空的线性表 Lc
是最后一个元素,则用next_e 返回它的后继,否则操作失 败,next_e无定义。
GetElem< L, i, &e >
〔求线性表中某个数据元素〕
初始条件:线性表 L 已存在,
且 1≤i≤LengthList(L)
操作结果:用 e 返回L中第 i 个元素的值。
LocateElem< L, e, compare< > >
bj 插入到 LC 中; 4.重复 2 和 3 两步,直至 LA 或 LB 中元素
被取完为止; 5.将 LA 表或 LB 表中剩余元素复制插入到
LC 表中.
// La 和 Lb 均非空,i = j = 1, k = 0 GetElem<La, i, ai>; GetElem<Lb, j, bj>; if <ai <= bj> { // 将 ai 插入到 Lc 中
例 2-3
归并两个"其数据元素按值非递减有序 排列"的有序表 LA 和 LB,求得有序表 LC 也具有同样特性.
设 La = <a1, …, ai, …, an>, Lb = <b1, …, bj, …,
ListInsert<Lc, ++k, ai>; ++i; } else { // 将 bj 插入到 Lc 中
ListInsert<Lc, ++k, bj>; ++j; }
void MergeList<List La, List Lb, List &Lc> { // 本算法将非递减的有序表 La 和 Lb 归并为 LcInitList<Lc>; // 构造空的线性表 Lc
是最后一个元素,则用next_e 返回它的后继,否则操作失 败,next_e无定义。
GetElem< L, i, &e >
〔求线性表中某个数据元素〕
初始条件:线性表 L 已存在,
且 1≤i≤LengthList(L)
操作结果:用 e 返回L中第 i 个元素的值。
LocateElem< L, e, compare< > >
bj 插入到 LC 中; 4.重复 2 和 3 两步,直至 LA 或 LB 中元素
被取完为止; 5.将 LA 表或 LB 表中剩余元素复制插入到
LC 表中.
// La 和 Lb 均非空,i = j = 1, k = 0 GetElem<La, i, ai>; GetElem<Lb, j, bj>; if <ai <= bj> { // 将 ai 插入到 Lc 中
第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
第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中表格作为一个数据的 组织形式,这种组织形式就是数据元素(记录)“一个接 一个地排列”。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
基本运算在顺序表上的实现
【例3】已知A、B、C为三个递增有序的顺序表,现要求对表
A作如下运算:删去哪些既在B中出现,又在C中出现的元素。 实现上述算法并分析其时间复杂度。 【思路分析】先在有序表B和C中找出公共元素,若该元素与有 序表A的data[i]相等,则将A中data[i]后面的元素前移一位 删除它。
6.设A和B中存放的是两个从小到大的顺序表,编写一个将A和B 中相同元素组成一个新的从小到大的有序表C的算法。 7.已知无表头结点的单链表,其中*p结点既不是首元结点,也 不是尾元结点。 (1)在*p结点后插入*S结点语句序列; (2)在*p结点前插入*S结点语句序列; (3)在表首插入*S结点的语句序列; (4)在表尾插入*S结点的语句序列。 8.在一个具有n个结点的有序单链表中,插入一个新结点并仍 然保持有序的时间复杂度是( )。 A.O(1) B.O(n) C.O(n2) D.O(nlog2n) 9.在链表、双链表和单循环链表中,若仅知道指针p指向某结 点,不知道头指针,能否将结点*p从相应的链表中删去(不允 许进行结点间数据域的复制)?若可以,其时间复杂度是多少?
单链表的基础要点
1.在单链表中,不能从当前节点出发访问到任一结点。 2.在单链表中,欲删除某一指定结点时,必须找到该结点的前 驱结点。 3.在单链表中,设置头结点的作用是:便于结点的插入和删除 操作。 4.单链表、静态链表、线性链表和顺序表中,需要分配较大空 间,插入和删除不需要移动元素的线性表,其存储结构是 ( )。 5.线性表的链式存储结构是一种顺序存取的存储结构。 6.链表不具有随机访问任一元素的特点。 7.不带头结点的单链表sq为空的判定条件是sq==NULL。 8.带头结点的单链表sq为空的判定条件是 ( sq next==NULL )。
(4)删除*p结点的直接前驱结点的语句是: (5)删除*p节点的语句是: 7、一个非空循环双链表中,在一个节点之后嘻哈如一个节点 *s的操作序列是:
习题
1.简述顺序表和链表两种存储方式之间的差异。 2.为什么在循环单链表中设置尾指针比设置头指针好? 3.在单链表中设置头结点的作用是什么? 4.下列哪些说法是错误的? (1)静态链表既有顺序存储的优点,又有动态链接的特点。 (2)静态链表中能容纳元素个数的最大值在定义时就确定了,以后不能再 增加。 (3)静态链表与动态链表在元素的插入、删除上类似,不需做元素的移动。 5.某线性表 中最常用的操作是在最后一个元素之后插入一个元素和删除第 一个元素,则采用以下哪种存储方式最节省运算时间。 (1)单链表 (2)仅有头指针的单循环列表 (3)双链表 (4)仅有尾指针的单循环列表
单链表的表示和实现
【例5】设计一个算法,通过一趟遍历确定单链表中确定值
最大的节点。 【思路解析】以p遍历单链表,在遍历时用p指向data域值最大 的节点,最后返回p。
【例6】设ha和hb分别是两个带头结点的非递减有序单链表
的表头指针,试设计一个算法,将这两个有序链表合并成一 个非递增有序的单链表。要求结果链表仍然使用原来两个单 链表的存储空间,不另外占用其他的存储空间。表中允许有 重复的数据。 【思路解析】用pa遍历ha,用pb遍历hb,新单链表hc先指向 *ha,pc始终指向hc的最后一个节点(初始时指向*hc)。比 较*pa和*pb的之data域值,将较小者连接到*hc之后。data 域值相同时,将两个节点均连接到*pc之后,同时让pc始终 指向最后一个节点。如此重复,指导ha和hb结束为止,再将 余下的链表连接到pc之后。
17.从一个具有n个结点的单链表中查找其值等于x的结点时,在查找成功的 情况下,平均需要比较( )个结点。 18.在一个具有n个结点的有序单链表中插入一个新结点的时间复杂度为 ( ) 。 19.给定有n个元素的有序表,建立一个有序单链表的时间复杂度是 ( )。 20.对于一个具有n个结点的单链表,在已知P所指结点后插入一个新结点的 时间复杂度是( )。
链表的应用
双链表的表示和实现
循环双链表
双链表的基础要点
1、在双链表中,能够从当前节点出发访问到任一结点。 2、非空循环双链表中,在q所指向的结点后面插入p所指的结 点过程已经依次进行了以下三步:p prior=q; p next=q next; q next=p 3、如果某链表中最常用的操作是在最后结点之后插入结点和 删除结点,则采用带头结点的循环双链表存储方式最节省运 算时间。 4、在循环双链表sq中,指针p所指结点为尾结点的条件: 5、带头结点的循环双链表sq为空表的条件是: 6、已知*p结点是某双链表的中间结点,则 (1)在*p结点后插入*s结点的语句序列: (2)在*p结点前插入*s结点的语句序列: (3)删除*p结点的直接后继结点的语句是:
循环单链表的表示和实现
【例7】有两个带头结点的循环单链表ha和hb,设计一算法
将它们首尾合并成一个带头结点的循环单链表hc。要求不改 变单链表ha和hb占用的空间。 【思路分析】本题要求复制ha和hb的结点并按照顺序生成hc。 其过程是:首先创建hc头结点,再由p遍历ha结点,边遍历 边复制生成结点*s,将*s链接到hc之后,对hb进行同样的操 作。
【例4】已知线性表(a0,a1,…,an-1),按顺序存储,且每个元
素都是均不相等的整数。设计把所有奇数移到所有偶数前边 的算法(要求时间最少,辅助空间最少)。 【思路分析】从左到右找偶数A.data[i],从右到左找奇数 A.data[j],将两者交换;循环这个过程,指导i大于j为止。
三、顺序实现的算法分析
7.在顺序表中插入和删除一个元素时,需要平均移动表的一半 元素,具体移动的元素个数与该元素的位置有关。 8.在长度为n的顺序表中插入和删除一个元素的时间复杂度均 为O(n)。 9.如果线性表最常用的操作是存取第i个元素及其前驱的值, 则采取顺序表存储方式节省时间。 10.若某线性表最常用的操作是存取任一指定序号的元素和在 最后插入和删除运算,则采取顺序表的存储方式最节省时间。 11.表长为n的顺序存储的线性表,当在任何位置上插入和删除 一个元素的概率相同时,插入一个元素所需移动元素的平均 个数为n/2,删除一个元素所需移动元素的平均个数为(n-1) /2。 12.将两个各具有n个元素的有序表归并成一个表,其最少的比 较次数为n。 13.在表长为n的线性表中的inselem(L,i,x)插入元素操作中, i的取值范围为:1≤i≤n+1。
第二章 线性表
线性表的基本运算
1.初始化:initlist(sq) 建立一个空表sq(只是建立一个构架,不含任何元素)。 2.求表长:getlen(sq) 返回线性表的长度。 3.读表元素:getelem(sq,i) 若1≤i≤ getlen(sq),返回线性表sq的第i个数据元素;否则, 返回NULL。 4.定位(按值查找):locate(sq,x) 若sq中存在一个或多个值与x相等的元素,返回这些元素的序 号最小的值;否则返回0。 5.插入:inselem(sq,x,i) 在线性表sq的第i个位置上增加一个以x为值的新元素,使sq由 (a1,…,ai-1,ai,…,an)变为( a1,…,ai-1,x,ai,…,an),参数i的 合法取值范围:1≤i≤n+1。
以节点的移动为标准操作。 插入算法的平均时间复杂度为:O(n) 删除算法的平均时间复杂度为:O(n)
顺序表的基础要点
1.线性表是具有n个数据元素的有限序列。 2.线性表的顺序存储结构具有三个弱点:其一,在删除和插入 操作时需移动大量的元素;其二,由于难以估计,必须预先 分配较大的空间;其三,表的容量难以扩充。 3.顺序表的存储结构通过元素的相对存储地址来表示元素之间 的关系。 4.线性表的顺序存储的优点:可随机存储元素,空间利用率高。 5.顺序表中逻辑上相邻的元素的物理位置必定紧邻。单链表中 逻辑上相邻的元素物理位置不一定紧邻。 6.顺序表是一种随机存储的数据结构。
10.在一个双链表中,请完成如下操作: (1)在*p结点之后插入结点*q的操作是: 答案:q next=p next;p next prior=q; p next=q;q prior=p; (2)在*p结点之前插入结点*q的操作是: 答案 :p prior next=q;q next=p; q prior=p prior;p prior=q; (3)删除*p结点的操作: 答案: p prior next=p next; p next prior=p prior; (4)删除*p结点之后的一个结点的操作是: 答案:p next=p next next;p next prior=p; 11.在长度为n(n>1)的( )上,删除第一个元素,其算法的时间复杂 度为O(n)。 A.只有首结点指针h的不带头结点的循环单链表 B.只有尾结点指针r的不带头结点的循环单链表 C.只有尾结点指针r的带头结点的循环单链表 D.只有头结点h的循环单链表 答案:A
6.删除:delelem(sq,i) 删除线性表sq的第i个元素ai,使sq由(a1,…,ai1,ai,ai+1,…,an)变为(a1,…,ai-1, ai+1,…,an),参数i的合法取 值范围:1≤i≤n。 7.输出:displist(sq) 按前后次序输出线性表sq的所有元素值。 应用以上基本运算可以实现线性表的其他运算。 例1.利用线性表的基本运算,编写线性表A中删除线性表B中出 现的所有元素。 例2.利用线性表的基本运算,编写将线性表A中和B中公共元素 生成线性表C的算法。
15.将如图所示的S所指结点加到P所指结点之后,其语句应为:
16.已知sq是带头结点的非空单链表,且*P既不是第一个结点也不是最后一 个结点,则: (1)删除*p结点的直接后继结点的语句序列是: (2)删除*p结点的直接前驱结点的语句序列是: (3)删除*p结点的语句序列是: (4)删除第一个结点的语句序列是: (5)删除最后一个结点的语句序列Байду номын сангаас:
9.非空的循环单链表sq的最后一个结点(由p所指向)满足 ( )。 10.非空的循环单链表sq的尾结点(由p所指向)满足条件 ( )。 11.在单链表中,删除*p结点的后继结点的语句是: 12.在一个长度为n(n>1)的单链表上,设有头和尾两个指针, 在以下操作:(1)删除单链表的第一个元素;(2)删除单链 表中最后一个元素;(3)在单链表第一个元素前插入一个新 元素;(4)在循环单链表最后一个元素后插入一个新元素。 执行哪几个操作与链表的长度无关? 13.一个无头结点的单链表中,在任一结点*P之前插入*S结点 时,可执行如下操作: 14.一个无头结点的单链表中,删除任意结点*P结点时,应执 行以下操作: