当前位置:文档之家› 数据结构1-4章习题答案

数据结构1-4章习题答案

第一章绪论一、选择题1.D2.C3.C4.B5.D6.C7.D8.C9.A 10.D11.D 12.B二、填空题1. 逻辑结构存储结构运算2. 集合结构线性结构树形结构图状结构3. 有穷性. 确定性. 可行性. 输入. 输出4. 顺序存储. 链式存储5. 数据元素6. 线性结构非线性结构三、简答题1. 尽管算法的含义与程序非常相似,但两者还是有区别的。

首先,一个程序不一定满有穷性,因为它不是一个算法。

其次,程序中的指令必须是计算机可以执行的,而算法中的指令却无此限制。

如果一个算法采用机器可执行的语言来书写,那么它就是一个程序。

2. 数据结构是指数据对象以及该数据对象集合中的数据元素之间的相互关系(数据元素的组织形式)。

例如:队列的逻辑结构是线性表(先进后出);队列在计算机中既可以采用顺序存储也可以采用链式存储;队列可进行删除数据元素. 插入数据元素. 判断是否为空队列,以及队列置空等操作。

3. 数据元素之间的逻辑关系,也称为数据的逻辑结构。

数据元素以及它们之间的相互关系在计算机存储器内的表示(又称映像)称为数据的存储结构,也称数据的物理结构。

4. 算法是对特定问题求解步骤的一种描述,它是指令的有限序列,其中每一条指令表示一个或者多个操作。

此外,一个算法还具有下列5个特性:(1)有穷性:一个算法必须在执行有穷步之后结束,即算法必须在有限时间内完成。

(2)确定性:算法中每一步必须有明确的含义,不会产生二义性。

并且,在任何条件下,算法只有唯一的一条执行路径,即对于相同的输入只能得出相同的输出。

(3)可行性:一个算法是能执行的,即算法中的每一步都可以通过已经实现的基本运算执行有限次得以实现。

(4)输入:一个算法有零个或者多个输入,它们是算法开始时对算法给出的初始量。

(5)输出:一个算法有一个或者多个输出,它们是与输入有特定关系的量5. 举例说明四种基本结构的区别:集合: 数据元素之间无任何关系,如集合A={x,5,t,&};线性结构: 数据元素之间存在一个对一个的关系,如线性表L=(2,3,4,5,7,10);树形结构: 数据元素之间存在一个对多个的关系,如文件系统目录管理;图状结构: 数据元素之间存在多个对多个的关系,如教学计划课程安排顺序图。

四. 算法设计题1. 执行时间为O(n)2. 执行时间为O(n3)3. 时间复杂度为O(log n)。

第二章线性表一、选择题1.B2.A3.B4.A5.C6.D7.A8.C9.C 10.B11.A 12.D 13.C 14.A 15.B16.C 17.A 18.A二、填空题1. 没有,1,没有,12. 长度,空表3. 移动4. 顺序存储结构,链式存储结构5. 顺序表,链表6. 移动,指针域7. 移动,前一个8. 头指针,指针域(链域)9. p->next->next10. p->next,q11. 链式12. 不相同13. 直接前驱,直接后继14. 运算(或操作)三、简答题1. 非空线性表的结构特征为:①有且只有一个称“第一个结点” a1 ,它无前驱;②有且只有一个称“最后结点” a n ,它无后继;③除以上结点外,其余结点均有一个直接前驱和一个直接后继。

2. 线性表的顺序存储结构具有如下两个基本特点:①线性表中所有元素所占的存储空间是连续的;②线性表中各数据元素在存储空间中是按逻辑顺序依次存放的。

3. 用一维数组存放线性表时,应注意数组的基本类型,要与线性表中数据元素的类型相同,而且该一维数组的长度,通常要定义得比线性表的实际长度大一些,以便对线性表进行各种运算。

4. 线性表顺序存储结构的优点是:简单,存储密度大,空间利用率高,对表中任意元素可直接确定其存储地址,随机访问存取效率高。

线性表顺序存储结构的缺点是:在顺序表中进行插入与删除操作时,需大量移动数据元素,时间开销大;再者,在顺序存储结构下,线性表的长度估计困难,并且当有多个顺序表同时共享计算机的存储空间时,不便于对存储空间进行动态分配。

5. 假设数据结构中的每一个数据结点对应于一个存储单元,这种存储单元称为存储结点,简称结点。

若每个结点由两部分组成:一部分用于存放数据元素值,称为数据域;另一部分用于存放指针,称为指针域。

其中指针用于指向该结点的前一个或后一个结点(即前驱或后继)。

通过每个结点的指针域,将n个结点按其逻辑顺序连接在一起而构成的数据存储结构,称为链式存储结构。

6.(1)开始结点(首结点):是指链表中的存储线性表中第一个数据元素a1的结点。

(2)头结点:为了操作方便,通常在链表的开始结点之前附加上一个结点,称为头结点。

一般情况下,头结点的数据域中不存储信息。

附设头结点的作用是为了对链表进行操作时更方便,可以对空表,非空表的情况以及对开始结点进行统一的处理。

(3)头指针:是指向链表中的第一个结点(可以是头结点,也可以是开始结点)的指针。

若链表中附设了头结点,则不管线性表是否为空,头指针均不为空;若链表中不设头结点,则线性表为空时,链表的头指针为空。

以上三个概念,对于单链表,循环链表和双向链表都适用。

7. 在单循环链表中,设置尾指针,可以更方便地判断链表是否为空。

8. 算法的功能是把单链表的第一个结点变成末尾结点。

返回的L指向原链表的第二个结点。

若原链表表示的线性表是(a1,a2,a3,a4......a n),则操作后表示的线性表为(a2,a3,a4......a n,a1)。

9. 由于向量中的元素按元素非递减有序排列,值相同的元素必为相邻的元素,因此依次比较相邻两个元素,若值相等,则删除其中一个,否则继续向后查询。

故算法功能是删除向量中多余的值相同的元素。

10.(1)单链表:当知道指针p指向某结点时,能够根据该指针找到其直接后继,但是不知道头指针,因此不能找到该结点的直接前驱,故无法删除该结点。

(2)双链表:根据指针p可以找到该结点的直接前驱和直接后继,因此,能够删除该结点。

(3)单循环链表:和双链表类似,根据指针p也可以找到该结点的直接前驱和直接后继,因此也可以删除该结点。

四、算法设计题1.【算法】void InsertInList(SequenList *L,DataType x){int i;for(i=0;i<L->Length(L)&&L->data[i]<x;i++); /*查找并比较*/Insert(L,i+1,x); /*调用顺序表插入算法*/ }2.【算法】LinkList *LinkTueList(LinkList *L1,LinkList *L2){ /*将两个单链表链接在一起*/LinkList *p,*q; p=L1;q=L2;while(p->next)p=p->next; /*查找终端结点*/p->next=q->next;free(q);return(L1); /*将L2的开始结点链接在L1之后*/}【时间复杂度分析】因为本算法的主要操作时间花费在查找L1的终端结点上,与L2的长度无关,所以本算法的时间复杂度为O(m)。

3.【算法】LinkList *JiaoJi(LinkList *A, LinkList *B){ LinkList *q,*p,*r,*s,*C;C = NULL;r = C;P = A; q = B;while (p&&q)if(p->data<q->data) p=p->next;else if(p->data==q->data){ s= (LinkList *)malloc(sizeof(LinkList));s->data=p->data;if(r!=NULL) r->next=s;else C=s;r=s;p=p->next;q=q->next;}else q=q->next;r->next=NULL;return( C );}4.【算法】void ShanChu(LinkList *L,int min,int max) /*设L为带头结点的单链表*/ { LinkList *p,*q,*s,*k;s=L; p=s->next;while(p!=NULL&&p->data>=max){s=p;p=p->next;} /*p指向第一个值小于max的结点,s指向其前驱*/ if(p!=NULL){ q=p;while(q!=NULL&&q->data>=min) /*q继续下移 */p=p->next; /* q指向第一个值不大于min的结点*/ s->next=q; /* 删除结点后的链接 */k=p->next;while(k!=q) /* 删除p结点到 q 结点之间的所有结点 */{ free(p); p=k; k=p->next;}}}【时间复杂度分析】前两个while循环和起来最多循环n次,第三个while循环最多循环n次,即删除n个结点,故算法的时间复杂度为O(n)。

5.【算法】LinkList *CharFen(LinkList *A){ LinkList *B,*p; /* p 指向A 表中序号为偶数的元素 */LinkList *ra, *rb; /* ra和rb将分别指向将创建的A表和B表的尾结点 */B=(LinkList *)malloc(sizeof(LinkList)); /* 创建B表头结点 */B->next=NULL; /* B表置空 */ra=A->next; rb=B; p=ra->next; /* p为工作指针,指向待分解的结点 */while(p!=NULL&&ra!=NULL){ ra->next=p->next; /* 做A表链接 */ra=p->next;rb->next=p; rb=p; /* p结点链接到B表的表尾,rb指向新的尾结点*/p=ra->next; /* 将p恢复为指向新的待处理结点 */}return(B);}6.【算法】void Rearrange(SequenList L) /* 本算法利用快速排序的划分重排线性表 */ { int i,j; /* i,j为工作指针(下标),初始指向线性表a的两端 */int t;i=0; j=Length(L)-1;while(i<j){ while(i<j && L->data[j]>=0) j++; /* 若当前元素>=0,则指针前移 */if(i<j) { t=L->data[i];L->data[i]=L->data[j];L->data[j]=t;i++; } /* 将负数前移 */while(i<j && L->data[i]<=0) i++; /* 当前元素为<=0,指针后移 */if(i<j) { t=L->data[i];L->data[i]=L->data[j];L->data[j]=t;j--; } /* 将正数后移 */}}7.【算法】void Delete_min(LinkList *L) /* L是带头结点的单链表 */{ LinkList *p, *pre, *q;p=L->next; /* p为工作指针。

相关主题