数据结构第2章
数据结构第二章课后答案
数据结构第二章课后答案数据结构第二章课后答案1. 线性表1.1 数组实现线性表Q1. 请说明线性表的定义,并结合数组实现线性表的特点进行解释。
线性表是由n(n≥0)个数据元素构成的有序序列,其中n表示线性表的长度。
数组实现线性表的特点是使用一组具有相同数据类型的连续存储空间存储线性表中的元素,通过下标访问和操作元素。
A1. 线性表的定义指出,线性表是由若干个数据元素组成的有序序列。
具体地,在数组实现线性表中,我们将元素存储在一组连续的内存空间中,通过下标访问和操作元素。
由于数组的存储空间具有连续性,这样的实现方式可以在O(1)的时间复杂度下进行元素的访问和修改操作。
1.2 链表实现线性表Q2. 请说明链表实现线性表的特点,并与数组实现进行比较。
链表实现线性表的特点是通过指针将线性表中的元素按照节点的形式连接起来,每个节点包含了存储的元素和指向下一个节点的指针。
与数组实现相比,链表的插入和删除操作更为高效,但是访问某个位置的元素需要从头开始遍历,时间复杂度较大。
A2. 链表实现线性表的特点是通过使用节点和指针将线性表中的元素连接起来。
每个节点中包含了一个存储的元素和指向下一个节点的指针。
链表的插入和删除操作的时间复杂度为O(1),因为只需要改变指针的指向即可。
但是,访问某个位置的元素需要从头开始遍历链表,所以时间复杂度为O(n)。
2. 栈和队列2.1 栈的定义和基本操作Q3. 请给出栈的定义和基本操作。
栈是一种特殊的线性表,它只能在表的一端进行插入和删除操作,该端称为栈顶。
栈的基本操作包括入栈(push)和出栈(pop),分别用于将元素压入栈和将栈顶元素弹出。
A3. 栈是一种特殊的线性表,它只能在表的一端进行插入和删除操作。
这个特定的一端称为栈顶,而另一端称为栈底。
栈的基本操作包括入栈(push)和出栈(pop)。
入栈操作将一个元素压入栈顶,出栈操作将栈顶元素弹出。
2.2 队列的定义和基本操作Q4. 请给出队列的定义和基本操作。
数据结构课后习题及解析第二章
例如m的初值为20;n=7,7个人的密码依次是:3,1,7,2,4,8,4,出列的顺序为6,1,4,7,2,3,5。
第二章答案
约瑟夫环问题
约瑟夫问题的一种描述为:编号1,2,…,n的n个人按顺时针方向围坐一圈,每个人持有一个密码(正整数)。一开始任选一个报数上限值m,从第一个人开始顺时针自1开始顺序报数,报到m时停止报数。报m的人出列,将他的密码作为新的m值,从他在顺时针方向上的下一个人开始重新从1报数,如此下去,直至所有的人全部出列为止。试设计一个程序,求出出列顺序。利用单向循环链表作为存储结构模拟此过程,按照出列顺序打印出各人的编号。
9.假设有一个循环链表的长度大于1,且表中既无头结点也无头指针。已知s为指向链表某个结点的指针,试编写算法在链表中删除指针s所指结点的前趋结点。
10.已知有单链表表示的线性表中含有三类字符的数据元素(如字母字符、数字字符和其它字符),试编写算法来构造三个以循环链表表示的线性表,使每个表中只含同一类的字符,且利用原表中的结点空间作为这三个表的结点空间,头结点可另辟空间。
r=p;
}
}
r->next=L->next;
printf("请输入第一个报数上限值m(m>0):");
scanf("%d",&m);
printf("*****************************************\n");
printf("出列的顺序为:\n");
q=L;
p=L->next;
7.试分别以不同的存储结构实现线性表的就地逆置算法,即在原表的存储空间将线性表(a1, a2..., an)逆置为(an, an-1,..., a1)。
第2章 线性表
《数据结构》第2章线性表共55题一、单选1. (1)分题目ID号:10545 题目难度:容易在一个长度为n的顺序存储的线性表中,向第i个元素(1≤i≤i十1)位量插入一个新元素时,需要从后向前依次后移【1】个元素。
A. n—iB. n—i十1C. n一i一1 D. i题目答案:B2. (1)分题目ID号:10546 题目难度:容易线性表是【1】。
A. 一个有限序列,可以为空B. 一个有限序列,不能为空C. 一个无限序列,可以为空D. 一个无序序列,不能为空题目答案:A3. (1)分题目ID号:10548 题目难度:容易在一个长度为n的线性表中,删除值为x的元素时需要比较元素和移动元素的总次数为【1】A. (n十1)/2B. n/2C. nD. n十l题目答案:C4. (1)分题目ID号:10549 题目难度:容易在一个顺序表的表尾插入一个元素的时间复杂度的量级为【1】A. ○(n)B. ○(1)C. ○(n*n)D. ○(lbn)题目答案:B5. (1)分题目ID号:10550 题目难度:容易单链表的存储密度为【1】A. 大于1B. 等于1C. 小于1D. 不能确定题目答案:C题目分析:存储密度=单链表数据项所占空间/结点所占空间结点所占空间由数据项所占空间和存放后继结点地址的链域,所以,存储密度小于1 。
6. (4)分题目ID号:10551 题目难度:难设单链表中指针p指向结点ai,指针q指着将要插入的新结点x,问:[1] 当x插在链表中两个数据元素ai和ai+1之间时,只要先修改【1】后修改【2】即可。
A.p一>next=qB.p一>next=p一>next->nextC.p->next=q->nextD.q一>next=p一>nextE.q->next=NULLF.q一>next=p[2] 在链表中最后一个结点an之后插入时,只要先修改【3】后修改【4】即可。
《数据结构与算法(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章 线性表
2.2.1 线性表的顺序存储—顺序表
线性表的顺序存储结构:把线性表中的所有元素按照 其逻辑顺序依次存储到从计算机存储器中指定存储位臵开 始的一块连续的存储空间中。 这样,线性表中第一个元素的存储位臵就是指定的存储 位臵,第i+1个元素(1≤i≤n-1)的存储位臵紧接在第i个元 素的存储位臵的后面。 线性表 逻辑结构 顺序表 存储结构
回true,否则返回false。
bool ListEmpty(SqList *L) {
return(L->length==0);
}
本算法的时间复杂度为O(1)。
(4)求线性表的长度ListLength(L)
该运算返回顺序表 L 的长度。实际上只需返回 length成员 的值即可。
int ListLength(SqList *L)
( 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) )个 元素的值。
void unionList(List LA,List LB,List &LC) { int lena,i; ElemType e; InitList(LC); for (i=1;i<=ListLength(LA);i++) //将LA的所有元素插入到Lc中 { GetElem(LA,i,e); ListInsert(LC,i,e); } lena=ListLength(LA); //求线性表LA的长度 for (i=1;i<=ListLength(LB);i++) { GetElem(LB,i,e); //取LB中第i个数据元素赋给e if (!LocateElem(LA,e)) //LA中不存在和e相同者,插入到LC中 ListInsert(LC,++lena,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值不合法”);
吉林大学数据结构_第二章 线性表
如何找指定位置的结点?
• 与顺序表不同,单链表无法直接访问指定 位置的结点,而是需要从哨位结点开始, 沿着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、其它操作 复制、分解、合并、分类等
数据结构(C++版)课后答案 (王红梅)第2章 线性表
第 2 章线性表课后习题讲解1. 填空⑴在顺序表中,等概率情况下,插入和删除一个元素平均需移动()个元素,具体移动元素的个数与()和()有关。
【解答】表长的一半,表长,该元素在表中的位置⑵顺序表中第一个元素的存储地址是100,每个元素的长度为2,则第5个元素的存储地址是()。
【解答】108【分析】第5个元素的存储地址=第1个元素的存储地址+(5-1)×2=108⑶设单链表中指针p 指向结点A,若要删除A的后继结点(假设A存在后继结点),则需修改指针的操作为()。
【解答】p->next=(p->next)->next⑷单链表中设置头结点的作用是()。
【解答】为了运算方便【分析】例如在插入和删除操作时不必对表头的情况进行特殊处理。
⑸非空的单循环链表由头指针head指示,则其尾结点(由指针p所指)满足()。
【解答】p->next=head【分析】如图2-8所示。
⑹在由尾指针rear指示的单循环链表中,在表尾插入一个结点s的操作序列是();删除开始结点的操作序列为()。
【解答】s->next =rear->next; rear->next =s; rear =s;q=rear->next->next; rear->next->next=q->next; delete q;【分析】操作示意图如图2-9所示:⑺一个具有n个结点的单链表,在指针p所指结点后插入一个新结点的时间复杂度为();在给定值为x的结点后插入一个新结点的时间复杂度为()。
【解答】Ο(1),Ο(n)【分析】在p所指结点后插入一个新结点只需修改指针,所以时间复杂度为Ο(1);而在给定值为x的结点后插入一个新结点需要先查找值为x的结点,所以时间复杂度为Ο(n)。
⑻可由一个尾指针唯一确定的链表有()、()、()。
【解答】循环链表,循环双链表,双链表2. 选择题⑴线性表的顺序存储结构是一种()的存储结构,线性表的链接存储结构是一种()的存储结构。
《数据结构C语言版》----第02章
同理可证:顺序表删除一元素的时间效率为: 同理可证:顺序表删除一元素的时间效率为: T(n)=(n-1)/2 ≈O(n) O(n) (
插入效 E = ∑ is 率: i=0
n
1 n n pi ( n − i ) = ∑ (n − i) = 2 n + 1 i=0
n −1 删除效 1 n −1 n −1 Edl = ∑ qi (n − i ) = ∑ (n − i ) = 率: n i =0 2 i =0
2.2 线性表的顺序表示和实现
顺序存储结构的线性表称作顺序表 1.顺序表的存储结构 顺序表的存储结构
实现顺序存储结构的方法是使用数组。数组把线性表 实现顺序存储结构的方法是使用数组。 使用数组 的数据元素存储在一块连续地址空间的内存单元中, 连续地址空间的内存单元中 的数据元素存储在一块连续地址空间的内存单元中,这样 线性表中逻辑上相邻的数据元素在物理存储地址上也相邻。 线性表中逻辑上相邻的数据元素在物理存储地址上也相邻。 数据元素间的逻辑上的前驱、 数据元素间的逻辑上的前驱、后继逻辑关系就表现在数据 元素的存储单元的物理前后位置上。 元素的存储单元的物理前后位置上。 顺序表的存储结构如图所示
2.线性表抽象数据类型 2.线性表抽象数据类型
数据集合:{ 的数据类型为DataType 数据集合 { a0, a1, … , an-1 }, ai的数据类型为 (1) ListInitiate(L) 初始化线性表 (2) ListLength(L) 求当前数据元素个数 操作集合: 操作集合 (3) ListInsert(L,i,x) 插入数据元素 (4) ListDelete(L,i,x) 删除数据元素 (5) ListGet(L,i,x) 取数据元素
printf("参数 不合法 \n"); 参数i不合法 参数 不合法! return 0;
数据结构课后习题与解析第二章
第二章习题1. 描述以下三个概念的区别:头指针,头结点,首元素结点。
2. 填空:(1)在顺序表中插入或删除一个元素,需要平均移动元素,具体移动的元素个数与有关。
(2)在顺序表中,逻辑上相邻的元素,其物理位置相邻。
在单链表中,逻辑上相邻的元素,其物理位置相邻。
(3)在带头结点的非空单链表中,头结点的存储位置由指示,首元素结点的存储位置由指示,除首元素结点外,其它任一元素结点的存储位置由指示。
3.已知L是无表头结点的单链表,且P结点既不是首元素结点,也不是尾元素结点。
按要求从下列语句中选择合适的语句序列。
a. 在P结点后插入S结点的语句序列是:。
b. 在P结点前插入S结点的语句序列是:。
c. 在表首插入S结点的语句序列是:。
d. 在表尾插入S结点的语句序列是:。
供选择的语句有:(1)P->next=S;(2)P->next= P->next->next;(3)P->next= S->next;(4)S->next= P->next;(5)S->next= L;(6)S->next= NULL;(7)Q= P;(8)while(P->next!=Q) P=P->next;(9)while(P->next!=NULL) P=P->next;(10)P= Q;(11)P= L;(12)L= S;(13)L= P;4. 设线性表存于a(1:arrsize)的前elenum个分量中且递增有序。
试写一算法,将X插入到线性表的适当位置上,以保持线性表的有序性。
5. 写一算法,从顺序表中删除自第i个元素开始的k个元素。
6. 已知线性表中的元素(整数)以值递增有序排列,并以单链表作存储结构。
试写一高效算法,删除表中所有大于mink且小于maxk的元素(若表中存在这样的元素),分析你的算法的时间复杂度(注意:mink和maxk是给定的两个参变量,它们的值为任意的整数)。
第二章基本数据结构及其运算
用这种方法查找,每次比较都可抛弃子表一半的 元素,查找效率较高 从该例可看出,数据元素在表中的排列顺序对查 找效率有很大的影响
例2、学生情况登记表信息查询 成绩在90分及以上的学生情况登记表
学 号 970156 970157 970158 970159 970160 970161 970162 970163 970164 … 姓 名 性 别 年龄 20 张小明 男 19 李小青 女 19 赵 凯 男 21 李启明 男 18 刘 华 女 19 曾小波 女 18 张 军 男 20 王 伟 男 19 胡 涛 男 … … … 成绩 86 83 70 91 78 90 80 65 95 … 学 号 姓 名 性别 男 女 男 女 年龄 21 19 19 17 成绩 91 90 95 93 970159 李启明 970161 曾小波 970164 胡 970168 梅 涛 玲
数据结构主要研究和讨论三方面问题:
1、数据元素之间的固有逻辑关系,称为数据的逻辑结构 2、数据元素及其关系在计算机中的存储方式,称为数据的 物理结构或存储结构
3、施加在数据结构上的操作,称为数据结构的运算。数据处 理的本质就是对数据结构施加各种运算,常见的运算有:查找、 排序、插入、删除等。
主要目的是提高数据处理的效率:
§2.1.3 数据结构的图形表示
D中的数据元素用中间标有元素值的方框表示, 称为数据结点(结点);R中的关系用一条有向线段 从前件结点指向后件结点。
例:设数据元素的集合为D = {di |1≤ i≤ 7的整数},画 出对应于下列关系所构成的数据结构的图形
①、R1={(d1,d3),(d1,d7),(d4,d5),(d3,d6),(d2,d4)} ②、R2={(di,dj)|i+j=5} ③、R3={(d2,d3)(d3,d1),(d1,d4),(d4,d6),d6,d5),(d5,d7)}
数据结构课后练习 - 第2章
的联系,所以可以从头结点开始查找任何一个元素。 (×) 4. 顺序存储的线性表可以实现随机存取。(√ )
二、单项选择题
1. 用单链表方式存储的线性表,存储每个结点需要两个域, 一个数据域,另一个是______B。
A. 当前结点所在的地址域
B. 指针域
C. 空指针域
D. 空闲域
2. 在具有n个结点的单链表中,实现__A____的操作,其算法 的时间复杂度都是O(n)。
A. 遍历链表和求链表的第i个结点
B. 在地址为p的结点之后插入一个结点
C. 删除开始结点
D. 删除地址为p的结点的后继结点
二、单项选择题
3. 已知一个顺序存储的线性表,设每个结点需占m个存储单元,若第一
学习要点
3. 熟练掌握在顺序存储结构上线性表的基本操作,如查 找、插入和删除的算法。
4. 熟练掌握在各种链表结构中线性表的基本操作,能在 实际应用中选用适当的链表结构。
5. 能够从时间与空间复杂度方面综合比较线性表两种存 储结构的不同特点及其适用场合。
一、判断对错题
1. 线性表中的元素可以是各种各样的,但同一线性表中 的数据元素具有相同的特性,因此属于同一数据对象。 ( )√
• 插入结点:移动元素次数n-i+1; • 删除结点:移动元素次数n-i。 • 决定因素:顺序表的长度以及插入、删除元素在表中
的位序。
4. 分析下述三个算法的具体功能。
ListNode *Demo1(LinkList L, ListNode *p)
{ //L是有头结点的单链表
ListNode *q=L->next;
数据结构导论 第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章线性表A
在线性表的第i个位臵前插入一个元素的示意图如下:
1 2 3 4 插入25 5 12 1
12
13 21
13
21 24 28 30 42 77
2
3 4 5 6 7 8
24
25
6
7 8
28
30 42 77
9
16
3)删除
删除线性表的第i个位臵上的元素
实现步骤: 将第i+1 至第n 位的元素向前移动一个位臵; 表长减1。 注意:事先需要判断,删除位臵i 是否合法? 应当符合条件:1≤i≤n 或 i=[1, n] 核心语句: for ( j=i+1; j<=n; j++ )
18
2.2.3 顺序表的运算效率分析
时间效率分析:
算法时间主要耗费在移动元素的操作上,因此 计算时间复杂度的基本操作(最深层语句频度) T(n)= O (移动元素次数) 而移动元素的个数取决于插入或删除元素的位臵.
讨论1:若在长度为 n 的线性表的第 i 位前 插入一个元素, 则向后移动元素的次数f(n)为: f(n) = n – i + 1
例2 分析学生情况登记表是什么结构。
学号 姓名 性别 年龄 班级
0406010402
0406010405 0406010406 0406010410 0406010413 :
陈杰
邓博 管杰 黄腾达 李荣智 : : :
2004级计软04-1班
2004级计软04-1班 2004级计软04-1班 2004级计软04-1班 2004级计软04-1班 :
InitList( &L ); DestoryList( &L ); //建空表,初始化 //撤销表,释放内存
数据结构算法(第二章)
∥算法2.1: 将所有在线性表Lb中但不在La中的数据元素插入到La中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);}}∥union∥算法2.2: 已知线性表La和Lb中的数据元素按值非递减排列。
∥归并La和Lb得到新的线性表Lc ,Lc的数据元素也接值非递减排列。
void MergeList(ListLa,List Lb, List &Lc){InitList(Lc);i=j=1; k=0;La_len=ListLength(La); Lb_len=ListLengtb(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; }else{ListInsert(Lc, ++k, bj); ++j;}}while(i<=La_len){GetElem(La, i++, ai); ListInsert(Lc,++k,ai);}while(j<=Lb_len){GetElem(Lb,j++,bj); ListInsert(Lc,++k,bj);}}∥MergeList∥算法 2.3:构造一个空的线性表L。
Status InitList_Sq(SqList &L){L.elem=(ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType));if(!L.elem) exit(OVERFLOW);L.length=0;L.listsize=LIST_INIT_SIZE;return oK;}∥InitList_Sq∥算法2.4:在顺序线性表L中第i个位置之前插入新的元素e,∥i的合法值为1≤i≤ListLength_ Sq(L)+1Status ListInsert_ Sq(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);L.elem=newbase;L.listsize+=LISTINCREMENT;}q=& (L.elem[i-l]);for(p=&(L.elem[L.length-l]);p>=q;--p)*(p+1)=*p;*q=e;++L.length;return OK;}∥Listlnsert_ Sq∥算法2.5:在顺序线性表L中删除第i个元素,并用e返回其值∥i的合法值为1≤i≤ListLength_ Sq(L)Status ListDelete_ Sq(SqList &L, int i,ElemType &e){if((i<1)|(1> L.length)) return ERROR;p=&(L.elem[i-l]);e=*p;q=L.elem+L.length -1;for(++p;p<=q;++p) *(p一1)=*p;--L.length;Return OK;}//ListDelete_Sq算法2.6:在顺序线性表L中查找第1个值与e满足compare()的元素的位序,//若找到,则返回其在L中的位序,否则返回0LocateElem_Sq(SqList_L, ElemType e, Status(*compare)(ElemType,ElemType)){;L.elem;while(i<=L.length&&!(*compare)(*p++,e)) ++i;if(i<=L.length) return i;else return0;}∥LocateElem_Sq∥算法2.7:已知顺序线性表La和Lb的元素按值非递减排列∥归并La和Lb得到新的顺序线性表Lc ,Lc的元素也按值非递减排列void MergeList_ Sq(SqList La, SqList Lb, SqList &Lc){pa=La.elem; pb=Lb.elem;Lc.listsize=Lc.length=La.length+Lb.length;pc=Lc.elem=(ElemType* )malloc(Lc.listsize* sizeof(ElemType));if(!Lc.elem) exit(OVERFLOW);pa_last=La.elem+La.length-l;pb_last=Lb.elem+Lb.length-l;while (pa<=pa_last&&pb<=pb_last){*pc++=*pa++;while (pa<=pa_ last) *pc++=*pa++;while (pb<=pb_ last) *pc++=*pb++;}∥MergeList_Sq∥算法2.8:L为带头绪点的单链表的头指针。
数据结构 第二章__线性表(本)
数据结构与算法华东师范大学计算机系杨沛第二章线性表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。
数据结构-C语言描述(第二版)(耿国华)章 (2)
2.1 线性表的概念及运算 2.2 线性表的顺序存储 2.3 线性表的链式存储 2.4 一元多项式的表示及相加
第2章 线 性 表 2.1 线性表的概念及运算
2.1.1 线性表的逻辑结构 线性表是n个类型相同的数据元素的有限序列,数据元素之
间是一对一的关系,即每个数据元素最多有一个直接前驱和一 个直接后继,如图2.1所示。例如:英文字母表(A,B,…, Z)就是一个简单的线性表,表中的每一个英文字母是一个数据 元素,每个元素之间存在唯一的顺序关系,如在英文字母表字 母B的前面是字母A,而字母B的后面是字母C。在较为复杂的线 性表中,数据元素(data elements)可由若干数据项组成,如 学生成绩表中,每个学生及其各科成绩是一个数据元素,它由 学号、姓名、各科成绩及平均成绩等数据项(item组成,常被称 为一个记录(record) ,含有大量记录的线性表称为文件(file)。 数据对象(dataobject)是性质相同的数据元素集合。
第2章 线 性 表
假设线性表中有n个元素,每个元素占k个单元,第 一个元素的地址为loc(a1),则可以通过如下公式计算出第i 个元素的地址loc(a -i):
loc(ai) =loc(a1)+(i-1)×k 其中loc(a -2.2 顺序表存储示意图
第2章 线 性 表
操作前提: 1≤i≤ListLength(L)。
表L已存在且非空,
操作结果: 删除L的第i个数据元素, 并用e返回其值, L的长度减1。
} ADT LinearList
第2章 线 性 表 2.2 线性表的顺序存储
2.2.1 线性表的顺序存储结构
线性表的顺序存储是指用一组地址连续的存储单元依 次存储线性表中的各个元素,使得线性表中在逻辑结构 上相邻的数据元素存储在相邻的物理存储单元中,即通过数据元 素物理存储的相邻关系来反映数据元素之间逻辑上的相邻关系。 采用顺序存储结构的线性表通常称为顺序表。
数据结构第2章典型例题解析
第2章线性表典型例题解析一、选择题1.线性表是具有n个(n≥0)的有限序列。
A.表元素B.字符C.数据元素D.数据项【分析】线性表是具有相同数据类型的n(n≥0)个数据元素的有限序列,通常记为(a1,a2,…,a n),其中n为表长,n=0时称为空表。
【答案】C2.顺序存储结构的优点是。
A.存储密度大B.插入运算方便C.删除运算方便D.可方便地用于各种逻辑结构的存储表示【分析】顺序存储结构是采用一组地址连续的存储单元来依次存放数据元素,数据元素的逻辑顺序和物理次序一致。
因此,其存储密度大。
【答案】A3.带头结点的单链表head为空的判断条件是。
A.head==NULL B.head->next==NULLC.head->next==head D.head!=NULL【分析】链表为空时,头结点的指针域为空。
【答案】B4.若某线性表中最常用的操作是在最后一个元素之后插入一个元素和删除第一个元素,则采用存储方式最节省运算时间。
A.单链表B.仅有头指针的单循环链表C.双链表D.仅有尾指针的单循环链表【分析】根据题意要求,该线性表的存储应能够很方便地找到线性表的第一个元素和最后一个元素,A和B都能很方便地通过头指针找到线性表的第一个元素,却要经过所有元素才能找到最后一个元素;选项C双链表若存为双向循环链表,则能很方便地找到线性表的第一个元素和最后一个元素,但存储效率要低些,插入和删除操作也略微复杂;选项D可通过尾指针直接找到线性表的最后一个元素,通过线性表的最后一个元素的循环指针就能很方便地找到第一个元素。
【答案】D5.若某线性表最常用的操作是存取任一指定序号的元素和在最后进行插入和删除运算,则利用存储方式最节省时间。
A.顺序表B.双链表C.带头结点的双循环链表D.单循环链表【分析】某线性表最常用的操作是存取任一指定序号的元素和在最后进行插入和删除运算。
因此不需要移动线性表种元素的位置。
根据题意要求,该线性表的存储应能够很方便地找到线性表的任一指定序号的元素和最后一个元素,顺序表是由地址连续的向量实现的,因此具有按序号随机访问的特点。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
基本操作: 结构初始化操作:InitList( &L ) 操作结果: 构造一个空的线性表L。 结构销毁操作: DestroyList( &L ) 初始条件: 线性表 L 已存在。 操作结果: 销毁线性表 L。 引用型操作: ListEmpty( L )(线性表判空) 初始条件:线性表L已存在。 操作结果:若L为空表,则返回TRUE,否则FALSE。 加工型操作:
LC中的元素 c=a(a<=b时) while ((i <= La_len) && (j <= Lb_len)) 或者 c=b(a>b) { // La 和 Lb 均不空 }
while (i<=La_len) // 若 La 不空 while (j<=Lb_len) // 若 Lb 不空
} // merge_list
3. 若 LA或LB已空将另一不空表中剩余元 素插入LC中。
例 2-2
void MergeList(List La, List Lb, List &Lc) { // 本算法将非递减的有序表 La 和 Lb 归并为 Lc
InitList(Lc); // 构造空的线性表 Lc i = j = 1; k = 0; La_len = ListLength(La); Lb_len = ListLength(Lb);
ListTraverse(L, visit( ))(遍历线性表)
初始条件:线性表L已存在,Visit() 为某个访问函数。 操作结果:依次对L的每个元素调用函数visit( )。一旦
visit( )失败,则操作失败。
加工型操作
ClearList( &L )(线性表置空)
初始条件: 线性表L已存在。 操作结果: 将L重置为空表。 PutElem( &L, i, &e ) (改变数据元素的值) 初始条件:线性表L已存在,且 1≤i≤LengthList(L) 。 操作结果:L中第i个元素赋值同e的值。
主讲教师:房斐斐
第2章 线性表
2.1 线性表的类型定义
2.2 线性表的顺序表示和实现
2.3 线性表的链式表示和实现 2.4 一元多项式的表示及相加
2.1线性表的类型定义
线性表定义:
一个线性表是n个数据元素的有限 序列,一种最简单的线性结构。
如 a1 , a2, , ai , an
物理结构
变化
1)插入 在线性表的第i个位置前插入一个元素
实现步骤: • 将第n至第i 位的元素向后移动一个位置; • 将要插入的元素写到第i个位置; • 表长加1。 注意:事先应判断: 插入位置i 是否合法?表是否已 满?
Status ListInsert_Sq(SqList &L, int i, ElemType e) { //在顺序表L的第 i 个元素之前插入新的元素e,1≤i≤L.length+1 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); // 存储分配失败 L.elem = newbase; // 新基址 L.listsize += LISTINCREMENT; // 增加存储容量 } q = &(L.elem[i-1]); // q 指示插入位置 for (p = &(L.elem[L.length-1]); p >= q; --p) *(p+1) = *p; // 插入位置及之后的元素右移 *q = e; // 插入e ++L.length; // 表长增1 算法时间复杂度为: return OK; O( ListLength(L) ) } // ListInsert_Sq
} // InitList_Sq
算法时间复杂度:O(1)
int LocateElem_Sq(SqList L, ElemType e, Status (*compare)(ElemType, ElemType)) {
// 在顺序表中查询第一个满足判定条件的数据元素, // 若存在,则返回它的位序,否则返回 0 i = 1; // i 的初值为第 1 元素的位序 p = L.elem; // p 的初值为第 1 元素的存储位置 while (i <= L.length && !(*compare)(*p++, e)) ++i;
} ADT List
引用型操作:
ListLength( L )(求线性表的长度)
初始条件: 线性表L已存在。 操作结果: 返回L中元素个数。
PriorElem( L, cur_e, &pre_e ) (求数据元素的前驱)
初始条件:线性表L已存在。 若cur_e是L的元素,但不是第一个,则用pre_e 操作结果:
例 2-1
假设:有两个集合A 和 B 分别用两个线性表 LA
和 LB 表示,即:线性表中的数据元素即为集合
中的成员。
现要求一个新的集合A=A∪B。
上述问题可演绎为:
要求对线性表作如下操作: 扩大线性表 LA,将存在于线性表LB 中而不存在
于线性表 LA 中的数据元素插入到线性表 LA 中去。
操作步骤:
if (i <= L.length) return i; else return 0;
} // LocateElem_Sq
算法的时间复杂度为: O( ListLength(L) )
例如:顺序表
L.elem L.listsize
23 75 41 38 54 62 17
p p p p p
L.length p
抽象数据类型线性表的定义:
ADT List {
数据对象:
D={ ai | ai ∈ElemSet, i=1,2,...,n, n≥0 } { 称 n 为线性表的表长; 称 n=0 时的线性表为空表。} 数据关系: R1={ <ai-1 ,ai >|ai-1 ,ai∈D, i=2,...,n } { 设线性表为 (a1,a2, . . . ,ai,. . . ,an), 称 i 为 ai 在线性表中的位序。}
初始条件:线性表L已存在,且 1≤i≤LengthList(L)。 操作结果:用 e 返回L中第 i 个元素的值。 LocateElem( L, e, compare( ) )(定位函数) 初始条件:线性表L已存在,e为给定值,compare( )是元
素判定函数。 返回L中第1个与e满足关系compare( )的元素的 操作结果: 位序。若这样的元素不存在,则返回值为0。
} SqList; // 俗称 顺序表
例如:顺序表
L.elem L.listsize
23 75 41 38 54 62 17
p p p p p
L.length
介绍三个有用的库函数(都在<stdlib.h>中): sizeof(x)——计算变量x的长度; malloc(m) —开辟m字节长度的地址空间,并返 回这段空间的首地址; free(p) ——释放指针p所指变量的存储空间, 即彻底删除一个变量。
线性表的基本操作在顺序表中的实现
InitList(&L) // 结构初始化
LocateElem(L, e, compare()) // 查找 ListInsert(&L, i, e) // 插入元素 ListDelete(&L, i) // 删除元素
Status InitList_Sq( SqList& L ) { // 构造一个空的线性表 L.elem = (ElemType*) malloc (LIST_ INIT_SIZEsizeof (ElemType)); if (!L.elem) exit(OVERFLOW); L.length = 0; L.listsize = LIST_INIT_SIZE return OK;
顺序映像
用一组地址连续的存储单元 依次存放线性表中的数据元素
以“存储位置相邻”表示有序对<ai-1,ai>
即:LOC(ai) = LOC(ai-1) + C
一个数据元素所占存储量↑
所有数据元素的存储位置均取决于第一个数据元
素的存储位置 LOC(ai) = LOC(a1) + (i-1)×C ↑基地址
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。
1.从线性表LB中依次察看每个数据元素;
GetElem(LB, i)→e
2.依值在线性表LA中进, equal( ))
3.若不存在,则插入之。
ListInsert(LA, n+1, e)
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); // 取Lb中第i个数据元素赋给e if (!LocateElem(La, e, equal( )) ) ListInsert(La, ++La_len, e); } } // union