数据结构(C语言版)习题及答案第二章
数据结构c语言版耿国华课后习题答案

数据结构c语言版耿国华课后习题答案数据结构是计算机科学中的一个重要领域,它涉及到数据的组织、管理和存储方式,以便可以高效地访问和修改数据。
C语言作为一种高级编程语言,提供了丰富的数据结构实现方法。
耿国华教授编写的《数据结构C语言版》一书,为学习者提供了深入理解和实践数据结构的机会。
以下是该书课后习题的一些参考答案。
# 第一章绪论1. 习题1:数据结构的定义是什么?- 参考答案:数据结构是计算机科学中用于组织、管理和存储数据的方式,以便可以高效地访问和修改数据。
2. 习题2:为什么需要学习数据结构?- 参考答案:学习数据结构有助于提高编程效率,优化算法性能,以及更好地解决实际问题。
# 第二章线性表1. 习题1:线性表的特点是什么?- 参考答案:线性表的特点是数据元素之间存在一对一的线性关系,可以顺序存储或链式存储。
2. 习题3:如何实现线性表的插入操作?- 参考答案:线性表的插入操作通常涉及找到插入位置,然后将新元素插入到该位置,并调整后续元素。
# 第三章栈和队列1. 习题1:栈的后进先出(LIFO)特性是什么?- 参考答案:栈的后进先出特性意味着最后插入的元素将是第一个被删除的元素。
2. 习题2:如何用C语言实现一个队列?- 参考答案:可以用数组或链表来实现队列。
队列的基本操作包括入队(enqueue)和出队(dequeue)。
# 第四章树和二叉树1. 习题1:二叉树的定义是什么?- 参考答案:二叉树是每个节点最多有两个子节点的树结构,通常分为左子节点和右子节点。
2. 习题3:二叉树的遍历方法有哪些?- 参考答案:二叉树的遍历方法包括前序遍历、中序遍历、后序遍历和层序遍历。
# 第五章图1. 习题1:图的基本概念有哪些?- 参考答案:图由顶点(节点)和边组成,可以表示对象之间的关系。
2. 习题2:图的存储方式有哪些?- 参考答案:图的存储方式主要有邻接矩阵和邻接表两种。
# 结语通过学习《数据结构C语言版》一书,读者可以掌握各种数据结构的基本概念、特性以及实现方法。
数据结构C语言版第一二章习题答案

数据结构C语言版第一二章习题答案Document number:BGCG-0857-BTDO-0089-2022第1章绪论习题1.简述下列概念:数据、数据元素、数据项、数据对象、数据结构、逻辑结构、存储结构、抽象数据类型。
2.试举一个数据结构的例子,叙述其逻辑结构和存储结构两方面的含义和相互关系。
3.简述逻辑结构的四种基本关系并画出它们的关系图。
4.存储结构由哪两种基本的存储方法实现?5.选择题(1)在数据结构中,从逻辑上可以把数据结构分成()。
A.动态结构和静态结构 B.紧凑结构和非紧凑结构C.线性结构和非线性结构 D.内部结构和外部结构(2)与数据元素本身的形式、内容、相对位置、个数无关的是数据的()。
A.存储结构 B.存储实现C.逻辑结构 D.运算实现(3)通常要求同一逻辑结构中的所有数据元素具有相同的特性,这意味着()。
A.数据具有同一特点B.不仅数据元素所包含的数据项的个数要相同,而且对应数据项的类型要一致C.每个数据元素都一样D.数据元素所包含的数据项的个数要相等(4)以下说法正确的是()。
A.数据元素是数据的最小单位B.数据项是数据的基本单位C.数据结构是带有结构的各数据项的集合D.一些表面上很不相同的数据可以有相同的逻辑结构(5)以下与数据的存储结构无关的术语是()。
A.顺序队列 B. 链表 C.有序表 D. 链栈(6)以下数据结构中,()是非线性数据结构A.树 B.字符串 C.队 D.栈6.试分析下面各程序段的时间复杂度。
(1)x=90; y=100;?while(y>0)if(x>100){x=x-10;y--;}else x++;(2)for (i=0; i<n; i++)for (j=0; j<m; j++)a[i][j]=0;(3)s=0;for i=0; i<n; i++)for(j=0; j<n; j++) s+=B[i][j];sum=s;(4)i=1;while(i<=n)i=i*3;(5)x=0;for(i=1; i<n; i++)for (j=1; j<=n-i; j++)x++;(6)x=n; //n>1y=0;while(x≥(y+1)* (y+1)) y++;(1)O(1)(2)O(m*n)(3)O(n2)n)(4)O(log3(5)因为x++共执行了n-1+n-2+……+1= n(n-1)/2,所以执行时间为O(n2)(6)O(n)第2章线性表1.选择题(1)一个向量第一个元素的存储地址是100,每个元素的长度为2,则第5个元素的地址是()。
数据结构(C语言版)习题及答案第二章

习题2.1选择题1、线性表的顺序存储结构是一种(A)的存储结构,线性表的链式存储结构是一种(B)的存储结构。
A、随机存取B、顺序存取C、索引存取D、散列存取2、对于一个线性,既要求能够进行较快的插入和删除,又要求存储结构能够反映数据元素之间的逻辑关系,则应该选择(B)。
A、顺序存储方式B、链式存储方式C、散列存储方式D、索引存储方式3、已知,L是一个不带头结点的单链表,p指向其中的一个结点,选择合适的语句实现在p结点的后面插入s结点的操作(B)。
A、p->next=s ; s->next=p->next ;B、s->next=p->next ; p->next=s ;C、p->next=s ; s->next=p ;D、s->next=p ; p->next=s ;4、单链表中各结点之间的地址( C D)。
A、必须连续B、部分地址必须连续C、不一定连续D、连续与否都可以5、在一个长度为n的顺序表中向第i个元素(0<i<=n+1)之前插入一个新元素时,需向后移动(B)个元素。
A、n-iB、n-i+1C、n-i-1D、i2.2填空题1、顺序存储的长度为n的线性表,在任何位置上插入和删除操作的时间复杂度基本上都一样。
插入一个元素大约移动表中的(n/2)个元素,删除一个元素时大约移动表中的((n-1)/2)个元素。
2、在线性表的顺序存储方式中,元素之间的逻辑关系是通过(物理顺序)来体现的;在链式存储方式,元素之间的逻辑关系是通过(指针)体现的。
3、对于一个长度为n的单链表,在已知的p结点后面插入一个新结点的时间复杂度为(o(1)),在p结点之前插入一个新结点的时间复杂度为(o(n)),在给定值为e的结点之后插入一个新结点的时间复杂度为(o(n))。
4、在双向链表中,每个结点包含两个指针域,一个指向(前驱)结点,另一个指向(后继)结点。
数据结构课后习题答案详解(C语言版_严蔚敏) 2

数据结构习题集答案(C语言版严蔚敏)第2章线性表2.1 描述以下三个概念的区别:头指针,头结点,首元结点(第一个元素结点)。
解:头指针是指向链表中第一个结点的指针。
首元结点是指链表中存储第一个数据元素的结点。
头结点是在首元结点之前附设的一个结点,该结点不存储数据元素,其指针域指向首元结点,其作用主要是为了方便对链表的操作。
它可以对空表、非空表以及首元结点的操作进行统一处理。
2.2 填空题。
解:(1) 在顺序表中插入或删除一个元素,需要平均移动表中一半元素,具体移动的元素个数与元素在表中的位置有关。
(2) 顺序表中逻辑上相邻的元素的物理位置必定紧邻。
单链表中逻辑上相邻的元素的物理位置不一定紧邻。
(3) 在单链表中,除了首元结点外,任一结点的存储位置由其前驱结点的链域的值指示。
(4) 在单链表中设置头结点的作用是插入和删除首元结点时不用进行特殊处理。
2.3 在什么情况下用顺序表比链表好?解:当线性表的数据元素在物理位置上是连续存储的时候,用顺序表比用链表好,其特点是可以进行随机存取。
2.4 对以下单链表分别执行下列各程序段,并画出结果示意图。
解:2.5 画出执行下列各行语句后各指针及链表的示意图。
L=(LinkList)malloc(sizeof(LNode)); P=L;for(i=1;i<=4;i++){P->next=(LinkList)malloc(sizeof(LNode));P=P->next; P->data=i*2-1;}P->next=NULL;for(i=4;i>=1;i--) Ins_LinkList(L,i+1,i*2);for(i=1;i<=3;i++) Del_LinkList(L,i);解:2.6 已知L是无表头结点的单链表,且P结点既不是首元结点,也不是尾元结点,试从下列提供的答案中选择合适的语句序列。
a. 在P结点后插入S结点的语句序列是__________________。
数据结构C语言版部分习题及答案[2]
![数据结构C语言版部分习题及答案[2]](https://img.taocdn.com/s3/m/e044a021e87101f69e319522.png)
第二章习题与解答一判断题1.线性表的逻辑顺序与存储顺序总是一致的。
2.顺序存储的线性表可以按序号随机存取。
3.顺序表的插入和删除操作不需要付出很大的时间代价,因为每次操作平均只有近一半的元素需要移动。
4.线性表中的元素可以是各种各样的,但同一线性表中的数据元素具有相同的特性,因此是属于同一数据对象。
5.在线性表的顺序存储结构中,逻辑上相邻的两个元素在物理位置上并不一定紧邻。
6.在线性表的链式存储结构中,逻辑上相邻的元素在物理位置上不一定相邻。
7.线性表的链式存储结构优于顺序存储结构。
8.在线性表的顺序存储结构中,插入和删除时,移动元素的个数与该元素的位置有关。
9.线性表的链式存储结构是用一组任意的存储单元来存储线性表中数据元素的。
10.在单链表中,要取得某个元素,只要知道该元素的指针即可,因此,单链表是随机存取的存储结构。
二单选题 (请从下列A,B,C,D选项中选择一项)1.线性表是( ) 。
(A) 一个有限序列,可以为空;(B) 一个有限序列,不能为空;(C) 一个无限序列,可以为空;(D) 一个无序序列,不能为空。
2.对顺序存储的线性表,设其长度为n,在任何位置上插入或删除操作都是等概率的。
插入一个元素时平均要移动表中的()个元素。
(A) n/2 (B) n+1/2 (C) n -1/2 (D) n3.线性表采用链式存储时,其地址( ) 。
(A) 必须是连续的;(B) 部分地址必须是连续的;(C) 一定是不连续的;(D) 连续与否均可以。
4.用链表表示线性表的优点是()。
(A)便于随机存取(B)花费的存储空间较顺序存储少(C)便于插入和删除(D)数据元素的物理顺序与逻辑顺序相同5.某链表中最常用的操作是在最后一个元素之后插入一个元素和删除最后一个元素,则采用( )存储方式最节省运算时间。
(A)单链表(B)双链表(C)单循环链表(D)带头结点的双循环链表6.循环链表的主要优点是( )。
(A)不在需要头指针了(B)已知某个结点的位置后,能够容易找到他的直接前趋(C)在进行插入、删除运算时,能更好的保证链表不断开(D)从表中的任意结点出发都能扫描到整个链表7.下面关于线性表的叙述错误的是( )。
数据结构第二章作业及答案

8
解答(续):
(2) 插入操作基本步骤: 1) 若i不合法或表L已满,算法结束并返回 ERROR;否则转2) 2) 将第i个元素及之后的所有元素均后移一个位置 3) 将新元素写入空出的位置; 4) 表长+1
9
解答(续):
插入操作算法(算法2.4 ):
Status ListInsert_Sq(SqList &L, int i , ElemType e) { //在顺序线性表L中第i个位置之前插入新的元素e, // i的合法值为1≤i≤ListLength_Sq(L)+1 if (i<1||i>L.length+1)return ERROR; //i值不合法 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; }//ListInsert_Sq
15
4.若某线性表最常用的操作是存取任一指定序号的元素和在最 后进行插入和删除运算,则利用( )存储方式最节省时间。 A.顺序表 B.双向链表 C.带头结点的双向循环链表 1 D.循环链表
数据结构(C语言版)第一二章习题答案

抽出时间去学习,凡事从小做起,不怕单调和重复,长期的积累坚持,想不成功,也难。
第1章绪论习题1.简述下列概念:数据、数据元素、数据项、数据对象、数据结构、逻辑结构、存储结构、抽象数据类型2.试举一个数据结构的例子叙述其逻辑结构和存储结构两方面的含义和相互关系3.简述逻辑结构的四种基本关系并画出它们的关系图4.存储结构由哪两种基本的存储方法实现?5.选择题(1)在数据结构中从逻辑上可以把数据结构分成()A.动态结构和静态结构 B.紧凑结构和非紧凑结构C.线性结构和非线性结构 D.内部结构和外部结构(2)与数据元素本身的形式、内容、相对位置、个数无关的是数据的()A.存储结构 B.存储实现C.逻辑结构 D.运算实现(3)通常要求同一逻辑结构中的所有数据元素具有相同的特性这意味着()A.数据具有同一特点B.不仅数据元素所包含的数据项的个数要相同而且对应数据项的类型要一致C.每个数据元素都一样D.数据元素所包含的数据项的个数要相等(4)以下说法正确的是()A.数据元素是数据的最小单位B.数据项是数据的基本单位C.数据结构是带有结构的各数据项的集合D.一些表面上很不相同的数据可以有相同的逻辑结构(5)以下与数据的存储结构无关的术语是()A.顺序队列 B. 链表 C. 有序表 D. 链栈(6)以下数据结构中()是非线性数据结构A.树 B.字符串 C.队 D.栈6.试分析下面各程序段的时间复杂度(1)x=90; y=100;while(y>0)if(x>100){x=x-10;y--;}else x++;(2)for (i=0; i<n; i++)for (j=0; j<m; j++)a[i][j]=0;(3)s=0;for i=0; i<n; i++)for(j=0; j<n; j++)s+=B[i][j];sum=s;(4)i=1;while(i<=n)i=i*3;(5)x=0;for(i=1; i<n; i++)for (j=1; j<=n-i; j++)x++;(6)x=n; //n>1y=0;while(x≥(y+1)* (y+1))y++;(1)O(1)(2)O(m*n)(3)O(n2)(4)O(log3n)(5)因为x++共执行了n-1+n-2+......+1= n(n-1)/2所以执行时间为O(n2)(6)O()第2章线性表1.选择题(1)一个向量第一个元素的存储地址是100每个元素的长度为2则第5个元素的地址是()A.110 B.108 C.100 D.120 (2)在n个结点的顺序表中算法的时间复杂度是O(1)的操作是()A.访问第i个结点(1≤i≤n)和求第i个结点的直接前驱(2≤i≤n)B.在第i个结点后插入一个新结点(1≤i≤n)C.删除第i个结点(1≤i≤n)D.将n个结点从小到大排序(3)向一个有127个元素的顺序表中插入一个新元素并保持原来顺序不变平均要移动的元素个数为()A.8 B.63.5 C.63 D.7(4)链接存储的存储结构所占存储空间()A.分两部分一部分存放结点值另一部分存放表示结点间关系的指针B.只有一部分存放结点值C.只有一部分存储表示结点间关系的指针D.分两部分一部分存放结点值另一部分存放结点所占单元数(5)线性表若采用链式存储结构时要求内存中可用存储单元的地址()A.必须是连续的 B.部分地址必须是连续的C.一定是不连续的 D.连续或不连续都可以(6)线性表L在()情况下适用于使用链式结构实现A.需经常修改L中的结点值B.需不断对L进行删除插入C.L中含有大量的结点D.L中结点结构复杂(7)单链表的存储密度()A.大于1 B.等于1 C.小于1 D.不能确定(8)将两个各有n个元素的有序表归并成一个有序表其最少的比较次数是()A.n B.2n-1 C.2n D.n-1(9)在一个长度为n的顺序表中在第i个元素(1≤i≤n+1)之前插入一个新元素时须向后移动()个元素A.n-i B.n-i+1 C.n-i-1 D.i(10) 线性表L=(a1a2......an)下列说法正确的是()A.每个元素都有一个直接前驱和一个直接后继B.线性表中至少有一个元素C.表中诸元素的排列必须是由小到大或由大到小D.除第一个和最后一个元素外其余每个元素都有一个且仅有一个直接前驱和直接后继(11) 若指定有n个元素的向量则建立一个有序单链表的时间复杂性的量级是()A.O(1) B.O(n) C.O(n2) D.O(nlog2n)(12) 以下说法错误的是()A.求表长、定位这两种运算在采用顺序存储结构时实现的效率不比采用链式存储结构时实现的效率低B.顺序存储的线性表可以随机存取C.由于顺序存储要求连续的存储区域所以在存储管理上不够灵活D.线性表的链式存储结构优于顺序存储结构(13) 在单链表中要将s所指结点插入到p所指结点之后其语句应为()A.s->next=p+1; p->next=s;B.(*p).next=s; (*s).next=(*p).next;C.s->next=p->next; p->next=s->next;D.s->next=p->next; p->next=s;(14) 在双向链表存储结构中删除p所指的结点时须修改指针()A.p->next->prior=p->prior; p->prior->next=p->next;B.p->next=p->next->next; p->next->prior=p;C.p->prior->next=p; p->prior=p->prior->prior;D.p->prior=p->next->next; p->next=p->prior->prior;(15) 在双向循环链表中在p指针所指的结点后插入q所指向的新结点其修改指针的操作是()A.p->next=q; q->prior=p; p->next->prior=q; q->next=q;B.p->next=q; p->next->prior=q; q->prior=p; q->next=p->next;C.q->prior=p; q->next=p->next; p->next->prior=q; p->next=q;D.q->prior=p; q->next=p->next; p->next=q; p->next->prior=q;2.算法设计题(1)将两个递增的有序链表合并为一个递增的有序链表要求结果链表仍使用原来两个链表的存储空间不另外占用其它的存储空间表中不允许有重复的数据void MergeList_L(LinkList &LaLinkList &LbLinkList &Lc){pa=La->next; pb=Lb->next;Lc=pc=La; //用La的头结点作为Lc的头结点while(pa && pb){if(pa->data<pb->data){ pc->next=pa;pc=pa;pa=pa->next;}else if(pa->data>pb->data) {pc->next=pb; pc=pb; pb=pb->next;} else {// 相等时取La的元素删除Lb的元素pc->next=pa;pc=pa;pa=pa->next;q=pb->next;delete pb ;pb =q;}}pc->next=pa?pa:pb; //插入剩余段delete Lb; //释放Lb的头结点}(2)将两个非递减的有序链表合并为一个非递增的有序链表要求结果链表仍使用原来两个链表的存储空间不另外占用其它的存储空间表中允许有重复的数据void union(LinkList& LaLinkList& LbLinkList& Lc) {pa = La->next; pb = Lb->next; // 初始化Lc=pc=La; //用La的头结点作为Lc的头结点Lc->next = NULL;while ( pa || pb ) {if ( !pa ) { q = pb; pb = pb->next; }else if ( !pb ) { q = pa; pa = pa->next; }else if (pa->data <= pb->data ) { q = pa; pa = pa->next; } else { q = pb; pb = pb->next; }q->next = Lc->next; Lc->next = q; // 插入}delete Lb; //释放Lb的头结点}(3)已知两个链表A和B分别表示两个集合其元素递增排列请设计算法求出A与B的交集并存放于A链表中void Mix(LinkList& LaLinkList& LbLinkList& Lc) {pa=la->next;pb=lb->next;∥设工作指针pa和pb;Lc=pc=La; //用La的头结点作为Lc的头结点while(pa&&pb)if(pa->data==pb->data)∥交集并入结果表中{ pc->next=pa;pc=pa;pa=pa->next;u=pb;pb=pb->next; delete u;}else if(pa->data<pb->data) {u=pa;pa=pa->next; delete u;} else {u=pb; pb=pb->next; delete u;}while(pa){ u=pa; pa=pa->next; delete u;}∥释放结点空间while(pb) {u=pb; pb=pb->next; delete u;}∥释放结点空间pc->next=null;∥置链表尾标记delete Lb; ∥注:本算法中也可对B表不作释放空间的处理(4)已知两个链表A和B分别表示两个集合其元素递增排列请设计算法求出两个集合A和B 的差集(即仅由在A中出现而不在B中出现的元素所构成的集合)并以同样的形式存储同时返回该集合的元素个数void Difference(LinkedList AB*n)∥A和B均是带头结点的递增有序的单链表分别存储了一个集合本算法求两集合的差集存储于单链表A中*n是结果集合中元素个数调用时为0{p=A->next;∥p和q分别是链表A和B的工作指针q=B->next; pre=A;∥pre为A中p所指结点的前驱结点的指针while(p!=null && q!=null)if(p->data<q->data){pre=p;p=p->next;*n++;} ∥ A链表中当前结点指针后移else if(p->data>q->data)q=q->next;∥B链表中当前结点指针后移else {pre->next=p->next;∥处理AB中元素值相同的结点应删除u=p; p=p->next; delete u;} ∥删除结点(5)设计算法将一个带头结点的单链表A分解为两个具有相同结构的链表B、C其中B表的结点为A表中值小于零的结点而C表的结点为A表中值大于零的结点(链表A的元素类型为整型要求B、C表利用A表的结点)(6)设计一个算法通过一趟遍历在单链表中确定值最大的结点ElemType Max (LinkList L ){if(L->next==NULL) return NULL;pmax=L->next; //假定第一个结点中数据具有最大值p=L->next->next;while(p != NULL ){//如果下一个结点存在if(p->data > pmax->data) pmax=p;p=p->next;}return pmax->data;(7)设计一个算法通过遍历一趟将链表中所有结点的链接方向逆转仍利用原表的存储空间void inverse(LinkList &L) {// 逆置带头结点的单链表 Lp=L->next; L->next=NULL;while ( p) {q=p->next; // q指向*p的后继p->next=L->next;L->next=p; // *p插入在头结点之后p = q;}}(8)设计一个算法删除递增有序链表中值大于mink且小于maxk的所有元素(mink和maxk是给定的两个参数其值可以和表中的元素相同也可以不同)void delete(LinkList &Lint minkint maxk) {p=L->next; //首元结点while (p && p->data<=mink){ pre=p; p=p->next; } //查找第一个值>mink的结点 if (p) {while (p && p->data<maxk) p=p->next;// 查找第一个值≥maxk 的结点q=pre->next; pre->next=p; // 修改指针while (q!=p){ s=q->next; delete q; q=s; } // 释放结点空间 }//if}(9)已知p指向双向循环链表中的一个结点其结点结构为data、prior、next三个域写出算法change(p)交换p所指向的结点和它的前缀结点的顺序知道双向循环链表中的一个结点与前驱交换涉及到四个结点(p结点前驱结点前驱的前驱结点后继结点)六条链void Exchange(LinkedList p)∥p是双向循环链表中的一个结点本算法将p所指结点与其前驱结点交换{q=p->llink;q->llink->rlink=p;∥p的前驱的前驱之后继为pp->llink=q->llink;∥p的前驱指向其前驱的前驱q->rlink=p->rlink;∥p的前驱的后继为p的后继q->llink=p;∥p与其前驱交换p->rlink->llink=q;∥p的后继的前驱指向原p的前驱p->rlink=q;∥p的后继指向其原来的前驱}∥算法exchange结束(10)已知长度为n的线性表A采用顺序存储结构请写一时间复杂度为O(n)、空间复杂度为O(1)的算法该算法删除线性表中所有值为item的数据元素[题目分析] 在顺序存储的线性表上删除元素通常要涉及到一系列元素的移动(删第i个元素第i+1至第n个元素要依次前移)本题要求删除线性表中所有值为item的数据元素并未要求元素间的相对位置不变因此可以考虑设头尾两个指针(i=1j=n)从两端向中间移动凡遇到值item的数据元素时直接将右端元素左移至值为item的数据元素位置void Delete(ElemType A[ ]int n)∥A是有n个元素的一维数组本算法删除A中所有值为item的元素{i=1;j=n;∥设置数组低、高端指针(下标)while(i<j){while(i<j && A[i]!=item)i++;∥若值不为item左移指针if(i<j)while(i<j && A[j]==item)j--;∥若右端元素值为item 指针左移if(i<j)A[i++]=A[j--];}[算法讨论] 因元素只扫描一趟算法时间复杂度为O(n)删除元素未使用其它辅助空间最后线性表中的元素个数是j。
数据结构C语言版部分习题及答案

国家计算机等级考试二级C语言公共基础知识总结第一章数据结构与算法1.1 算法算法:是指解题方案的准确而完整的描述。
算法不等于程序,也不等计算机方法,程序的编制不可能优于算法的设计。
算法的基本特征:是一组严谨地定义运算顺序的规则,每一个规则都是有效的,是明确的,此顺序将在有限的次数下终止。
特征包括:(1)可行性;(2)确定性,算法中每一步骤都必须有明确定义,不充许有模棱两可的解释,不允许有多义性;(3)有穷性,算法必须能在有限的时间内做完,即能在执行有限个步骤后终止,包括合理的执行时间的含义;(4)拥有足够的情报。
算法的基本要素:一是对数据对象的运算和操作;二是算法的控制结构。
指令系统:一个计算机系统能执行的所有指令的集合。
基本运算包括:算术运算、逻辑运算、关系运算、数据传输。
算法的控制结构:顺序结构、选择结构、循环结构。
算法基本设计方法:列举法、归纳法、递推、递归、减斗递推技术、回溯法。
算法复杂度:算法时间复杂度和算法空间复杂度。
算法时间复杂度是指执行算法所需要的计算工作量。
算法空间复杂度是指执行这个算法所需要的内存空间。
1.2 数据结构的基本基本概念数据结构研究的三个方面:(1)数据集合中各数据元素之间所固有的逻辑关系,即数据的逻辑结构;(2)在对数据进行处理时,各数据元素在计算机中的存储关系,即数据的存储结构;(3)对各种数据结构进行的运算。
数据结构是指相互有关联的数据元素的集合。
数据的逻辑结构包含:(1)表示数据元素的信息;(2)表示各数据元素之间的前后件关系。
数据的存储结构有顺序、链接、索引等。
线性结构条件:(1)有且只有一个根结点;(2)每一个结点最多有一个前件,也最多有一个后件。
非线性结构:不满足线性结构条件的数据结构。
1.3 线性表及其顺序存储结构线性表是由一组数据元素构成,数据元素的位置只取决于自己的序号,元素之间的相对位置是线性的。
在复杂线性表中,由若干项数据元素组成的数据元素称为记录,而由多个记录构成的线性表又称为文件。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
习题2.1选择题1、线性表的顺序存储结构是一种(A)的存储结构,线性表的链式存储结构是一种(B)的存储结构。
A、随机存取B、顺序存取C、索引存取D、散列存取2、对于一个线性,既要求能够进行较快的插入和删除,又要求存储结构能够反映数据元素之间的逻辑关系,则应该选择(B)。
A、顺序存储方式B、链式存储方式C、散列存储方式D、索引存储方式3、已知,L是一个不带头结点的单链表,p指向其中的一个结点,选择合适的语句实现在p结点的后面插入s结点的操作(B)。
A、p->next=s ; s->next=p->next ;B、s->next=p->next ; p->next=s ;C、p->next=s ; s->next=p ;D、s->next=p ; p->next=s ;4、单链表中各结点之间的地址( C D)。
A、必须连续B、部分地址必须连续C、不一定连续D、连续与否都可以5、在一个长度为n的顺序表中向第i个元素(0<i<=n+1)之前插入一个新元素时,需向后移动(B)个元素。
A、n-iB、n-i+1C、n-i-1D、i2.2填空题1、顺序存储的长度为n的线性表,在任何位置上插入和删除操作的时间复杂度基本上都一样。
插入一个元素大约移动表中的(n/2)个元素,删除一个元素时大约移动表中的((n-1)/2)个元素。
2、在线性表的顺序存储方式中,元素之间的逻辑关系是通过(物理顺序)来体现的;在链式存储方式,元素之间的逻辑关系是通过(指针)体现的。
3、对于一个长度为n的单链表,在已知的p结点后面插入一个新结点的时间复杂度为(o(1)),在p结点之前插入一个新结点的时间复杂度为(o(n)),在给定值为e的结点之后插入一个新结点的时间复杂度为(o(n))。
4、在双向链表中,每个结点包含两个指针域,一个指向(前驱)结点,另一个指向(后继)结点。
5、对于循环链表来讲,逐个访问各个结点的结束判断条件是(设P为指向结点的指针,L为链表的头指针,则p->next= =L)。
2.3读下面的程序段,画出执行过程的示意图及所完成的功能。
1、 # define N 6void main ( ){ ListSq L ;int A[ N ];int i , elem ;InitList(L); //初始化函数for ( int j=0; j<N; j++)scanf("%d",&A[ j ]) ;for ( int m=0; m<N; m++)InsertList ( L , m ,A[m]) ;PrintList( L ) ; // 输出函数}L.e[0]L.e[1]L.e[2]L.e[3]L.e[4]L.e[5] 1题示意图L2题示意图功能:先初始化一个顺序表,然后根据数组A中元素的顺序创建顺序表,并输出顺序表的全部元素。
2、 Lnode *CreateList( ){ Lnode *L,*S;int x,y;L=malloc(sizeof(Lnode));L->data=x;s=malloc(sizeof(Lnode));s->data=y;L->next=s;s->next=NULL;return L;}功能:创建一个两个结点的不带头结点的单链表,两个结点的值分别为X和Y,L为单链表的头指针。
2.4 算法题1、编写在两种存储方式下,删除线性表中多余的值相同元素的算法。
解:顺序存储方式下:void del(ListSq &L){ int i=0;while (i<L.len-1){ int j=i+1;while (j<L.len)if (L.e[i]= =L.e[j]){ for (int k=j+1;k<L.len;k++)L.e[k-1]=L.e[k];L.len--;}else j++;i++;}}链式存储方式下:void del(Lnode *L){ Lnode *p=L->next;while (p->next!=NULL){ Lnode *q=p->next;Lnode *r=p;while (q!=NULL)if (q->data= =p->data){ r->next=q->next; free(q); q=r->next; }else {r=q; q=q->next; }p=p->next;}}2、已知,顺序表的元素类型为整型,编写将该顺序表分成两个顺序表的算法,一个存放所的奇数元素,另一个存放所的偶数元素。
解:void fenSq(ListSq L, ListSq &La, ListSq &Lb ){ int j=0,k=0;for (int i=0;i<L.len;i++)if (L.e[i]%2= =0){ Lb.e[j]=L.e[i]; j++; }else { La.e[k]=L.e[i]; k++; }La.len=k;Lb.len=j;}3、编写一个统计单循环链表的结点个数的算法。
解:int count(Lnode *L){ Lnode *p=L->next;int n=0;while(p!=L){ n++; p=p->next; }return n;}4、编写删除有序单链表中元素值大于min并且小于max的全部元素的算法。
如果给定的表是无序的,如何改写上面的算法。
解:void del4(Lnode *L,Elemtype min , Elemtype max ){ Lnode *q,*s,*p ;p=L->next; q=L;while (p!=NULL&&p->date<=min){ q=p; p=p->next; }if (p!=NULL)//表示存在大于min的结点,最后一个小于等于min的结点为q结点{while (p!=NULL&&p->date<max)p=p->next;if (p!=NULL)// 表示存在大于等于max的结点,既p结点while (q->next!=p) //删除q的后继结点到p的前驱结点为止的所有结点{ s=q->next; q->next=s->next; free(s); }else{ s=q->next; q->next=NULL;//q以后的结点全部要删除while (s!=NULL){ p=s->next; free(s); s=p; }}}5、用顺序表来求集合的并集、交集和差集,也可以用链表来实现以上操作。
(作为上机实践题目)# include < stdio.h >typedef int Elemtype ;# define maxlen 100# define N 30struct ListSq{Elemtype e [ maxlen ] ;int len ;};//顺序表的创建算法void Create_Sq( ListSq &L , Elemtype A[ ] , int n ) {int i ;for ( i=0 ; i<n ; i++ )L.e[i] =A[i];L.len=n ;}//顺序表的输出算法void PrintList( ListSq L ){printf("当前集合为:\n");for ( int i=0; i<L.len; i++)printf("%d\t" , L.e [ i ] ) ;printf ( "\n" ) ;}void bingji(ListSq L1,ListSq L2,ListSq &L3){for(int k=0;k<L1.len;k++)L3.e[k]=L1.e[k];L3.len=L1.len;for (int i=0;i<L2.len;i++){int j=0;while((j<L1.len)&&(L2.e[i]!=L1.e[j]))j++;if (j>=L1.len){L3.e[L3.len]=L2.e[i];L3.len++;}}}void jiaoji(ListSq L1,ListSq L2,ListSq &L3){int k=0;for(int i=0;i<L1.len;i++){int j=0;while((j<L2.len)&&(L1.e[i]!=L2.e[j])) j++;if(j<L2.len)L3.e[k++]=L1.e[i];}L3.len=k;}void chaji(ListSq L1,ListSq L2,ListSq &L3) {int k=0;for(int i=0;i<L1.len;i++){int j=0;while((j<L2.len)&&(L1.e[i]!=L2.e[j])) j++;if(j>=L2.len)L3.e[k++]=L1.e[i];}for(int m=0;m<L2.len;m++){int n=0;while((n<L1.len)&&(L2.e[m]!=L1.e[n])) n++;if(n>=L1.len)L3.e[k++]=L2.e[m];}L3.len=k;}//主函数void main ( ){ListSq L1,L2,L3 ;L3.len=0;int A[ N ];int m,n,c;printf("请输入线性表L1的元素个数:\n"); scanf("%d",&m);printf("请输入线性表L1的元素:\n");for ( int j=0; j<m; j++)scanf("%d",&A[ j ]) ;Create_Sq( L1 , A , m );PrintList( L1 ) ;printf("请输入线性表L2的元素个数:\n");scanf("%d",&n);printf("请输入线性表L2的元素:\n");for ( int w=0; w<n; w++)scanf("%d",&A[ w ]) ;Create_Sq( L2 , A , n );PrintList( L2 ) ;while(1){printf("请按提示进行输入:\n");printf("实现两个集合的并集,请输入1:\n");printf("实现两个集合的交集,请输入2:\n");printf("实现两个集合的差集,请输入3:\n");printf("退出,请输入4:\n");scanf("%d",&c);switch(c){case 1:{bingji(L1,L2,L3);PrintList( L3 ) ;break;}case 2:{jiaoji(L1,L2,L3);PrintList( L3 ) ;break;}case 3:{chaji(L1,L2,L3);PrintList( L3 );break;}case 4:return;default: printf("输入有误!\n");}}}6、用循环单链表来实现约瑟夫问题。