数据结构第二版课后答案陈雁著高等教育出版社.docx
《数据结构第二版课后答案陈雁著高等教育出版社.docx》由会员分享,可在线阅读,更多相关《数据结构第二版课后答案陈雁著高等教育出版社.docx(64页珍藏版)》请在冰豆网上搜索。
数据结构第二版课后答案陈雁著高等教育出版社
第一章
习题
1、简述下列术语:
数据元素、数据、数据对象、数据结构、存储结构和算法
解:
数据元素:
数据的基本单位。
在计算机程序中通常作为一个整体进行考虑和处理。
数据:
信息的载体。
是描述客观事物的数字、字符以及所有能输入到计算机中并被计算机程序处理的符号的集合。
数据对象:
性质相同的数据元素的集合,是数据的一个子集。
数据结构:
相互之间存在着一种或多种关系的数据元素的集合,包括数据的逻辑结构和物理结构两方面的内容。
存储结构:
数据的逻辑结构在计算集中的表示方式,包含顺序存储方法、链接存储方法、索引存储方法、散列存储方法。
算法:
对特定问题求解步骤的一种描述,它是指令或语句的有限序列,并具有有穷型、确定性、可行性、输入和输出五个重要特性。
2、试写一算法,自大至小依次输出顺序读入的三个整数x,y和z的值
解:
voidf1(void)
{
intx,y,z;
printf("enterx,y,z:
");
scanf("%d,%d,%d",&x,&y,&z);
if(x>y)
if(y>z)
printf("%d,%d,%d",x,y,z);
else
if(x>z)
printf("%d,%d,%d",x,z,y);
else
printf("%d,%d,%d",z,x,y);
else
if(x>z)
printf("%d,%d,%d",y,x,z);
else
if(z>y)
printf("%d,%d,%d",z,y,x);
else
printf("%d,%d,%d",y,z,x);
}
3、举出一个数据结构的例子,叙述其逻辑结构、存储结构、运算等三方面的内容
解:
4、分析下列算法的时间复杂度:
(1)
intprime(intn)
{
for(i=2;iif(n%i==0)
return0;
return1;
}
解:
O(n1/2)
(2)
longsun(intn)
{
s=0;
for(i=1;i<=n;i++)
{
for(p=1,j=1;j
p=p*j;
s+=p;
}
returns;
}
解:
O(n2)
第二章
习题
1、描述以下三个概念的区别:
头指针、头结点、首元结点(第一个元素结点)。
头指针:
指针,指向头节点的指针
头结点:
结点,其指针域指向首元节点
首元结点:
结点,第一个元素的表示形式
2、试比较顺序存储结构和链式存储结构的优缺点。
优点
缺点
顺序存储
可随机存储
内存存储密度高
实现插入、删除时的效率低
要求连续存储空间
链式存储
实现插入、删除时的效率高
不要求连续存储空间
不能随机存储
存储数据时需实用额外内存空间(如地址域)
3、设计算法,删除顺序表中值为x的所有结点。
intDelete_Sq(SqList*L,ELEMTPx)
{
intn=0,i=1;
if(L->len==0)return-1;/*表已空*/
while(i<=L->len)
if(L->elem[i]=x)
{
for(j=i;j<=L->len-1;j++)
L->elem[j]=L->elem[j+1];/*被删除元素之后的元素左移*/
--L->len;
}
else
i++;
return1;
}
4、设线性表(a1,a2,…,an)存储在带表头结点的单链表中,试设计算法,求出该线性表中值为x的元素的序号。
如果x不存在,则序号为0。
intIndex_Linkst(LNode*H,ELEMTPx)
{
p=H->next;j=1;f=0;/*P指向第一个结点,j为计数器,f为标志*/
while(p)
{
if(p->data!
=x)
{
j++;
p=p->next;
}
else
f=1;
}
if(f=1)
returnj;
else
return0;
}
5、在一个非递减有序线性表中,插入一个值为x的元素,使插入后的线性表仍为非递减有序。
分别写出用顺序表和单链表表示时的算法。
顺序表:
intInsert_Sq(SqList*L,ELEMTPx)
{
if(L->len==MAXSIZE-1)return-1;/*表已满*/
if(x>=L->elem[L->len])
{
L->elem[L->len+1]=x;
L->len+=1;
}
else
{
i=1;
while(x>=L->elem[i])
i++;
for(j=L->len;j>=i;j--)
L->elem[j+1]=L->elem[j];
L->elem[i]=x;
L->len+=1;
}
return1;
}
单链表:
intInsert_Linkst(LNode*H,ELEMTPx)
{
p=H;
s=(LNode*)malloc(sizeof(LNode));
if(s)
{
s->data=x;
s->next=NULL;
}
else
return0;
while(p->next)
if(p->next->datap=p->next;
else
{
s->next=p->next;
p->next=s;/*插入*/
return1;
}/*Insert_Linkst*/
p->next=s;
return1;
}
6、设一个线性表L=(a1,a2,…,an),编写算法将其逆置,即成为(an,an-1,…a2,a1)。
要求逆置后的线性表仍占用原来的存储空间,并且用顺序和单链表两种方法表示,写出不同的处理过程。
顺序表:
voidinverse_Sq(SqList*L)
{
inti;
ELEMTPx;
for(i=1;i<=L->len/2;i++)
{
x=L->elem[i];
L->elem[i]=L->elem[L->len-i+1];
L->elem[L->len-i+1]=x;
}
}
单链表:
voidinverse_Linkst(LNode*H)
{
d=h->next;
if(d!
=NULL)
{
p=d->next;
while(p)
{
t=p->next;
p->next=d;
d=p;
p=t;
}
h=d;
}
}
7、设两个单链表A和B,它们的数据元素分别为(x1,x2,…,xm)和(y1,y2,…,yn)。
设计一个算法将它们合并为一个单链表C,使得:
当m≥n时,C=(x1,y1,x2,y2,...,xn,yn,...,xm)
当n>m时,C=(y1,x1,y2,x2,...,ym,xm,...,yn)。
LNode*Link_Linkst(LNode*A,LNode*B)
{
p=A->next;
q=B->next;
m=0;
n=0;
while(p)
{
m++;
p=p->next;
}
while(q)
{
n++;
q=q->next;
}
if(m>=n)
{
p=A->next;
q=B->next;
C=A;
}
else
{
p=B->next;
q=A->next;
C=B;
}
while(q)
{
t=p->next;
p->next=q;
q=q->next;
p->next->next=t;
p=t;
}
returnC;
}
8、试写一算法,在无表头结点的单链表中值为a的结点前插入一个值为b的结点,如果a不存在,则把b插在表尾。
将该算法与第2.3.2节中的算法2.7进行比较。
voidInsertx_Linkst(LNode*H,Elemtpa,Elemtpb)
{
s=(LNode*)malloc(sizeof(LNode));
s->data=b;
s->next=NULL;
if(H==NULL)
{
H=s;
}
else
{
p=H;
q=p->next;
if(p->data==a)/*对首元节点处理*/
{
s->next=p;
H=s;
}
else
{
while(q&&q->data!
=a)
{
p=q;
q=q->next;
}
p->next=s;
s->next=q;
}
}
}
9、假设有一个单向循环链表,其结点包含三个域:
data,pre和next,其中data为数据域,next为指针域,其值为后继结点的地址,pre也为指针域,其初值为空(NULL),试设计算法将此单向循环链表改为双向循环链表。
voidChange_Linkst(LNode*H)
{
q=H;
p=H->next;
while(p)
{
p->pre=q;
q=p;
p=p->next;
}
H->pre=q;
q->next=H;
}
10、已知二维数组A[5][7],其每个元素占四个存储单元,且A[0][0]的存储地址为1100,试求出元素A[3][5]的存储地址(分别讨论以行为序和以列为序方式存储时的结论)。
行为序
1100+4*(3*7+5)=1204
列为序
1100+4*(5*5+3)=1212
11、设有一个二维数组A[M][N],对以下三种情况分别编写算法:
(1)求数组A的最外围元素之和;
(2)求从A[0][0]开始的互不相邻的各元素之和;
(3)当M=N时,分别求两条对角线上的元素之和,否则输出M≠N的信息。
intA1(intA[M][N])/*求数组A的最外围元素之和*/
{
s=0;
for(i=0;i{
if(i==0||i==M-1)
for(j=0;js+=A[i][j];
else
s+=A[i][0]+A[i][N-1];
}
returns;
}
intA2(ELEMTPA[M][N])/*求从A[0][0]开始的互不相邻的各元素之和*/
{
s=0;
for(i=0;i{
if(i%2==0)
j=0;
else
j=1;
for(;js+=A[i][j];
}
returns;
}
voidA3(intA[M][N],int*s1,int*s2)/*分别求