数据结构与算法分析课后习题答案.docx
《数据结构与算法分析课后习题答案.docx》由会员分享,可在线阅读,更多相关《数据结构与算法分析课后习题答案.docx(18页珍藏版)》请在冰豆网上搜索。
数据结构与算法分析课后习题答案
数据结构和算法分析课后习题答案
【篇一:
《数据结构和算法》课后习题答案】
>2.3.2判断题
2.顺序存储的线性表可以按序号随机存取。
(√)
4.线性表中的元素可以是各种各样的,但同一线性表中的数据元素具有相同的特性,因此属于同一数据对象。
(√)
6.在线性表的链式存储结构中,逻辑上相邻的元素在物理位置上不一定相邻。
(√)
8.在线性表的顺序存储结构中,插入和删除时移动元素的个数和该元素的位置有关。
(√)
9.线性表的链式存储结构是用一组任意的存储单元来存储线性表中数据元素的。
(√)
2.3.3算法设计题
1.设线性表存放在向量a[arrsize]的前elenum个分量中,且递增有序。
试写一算法,将x插入到线性表的适当位置上,以保持线性表的有序性,并且分析算法的时间复杂度。
【提示】直接用题目中所给定的数据结构(顺序存储的思想是用物理上的相邻表示逻辑上的相邻,不一定将向量和表示线性表长度的变量封装成一个结构体),因为是顺序存储,分配的存储空间是固定大小的,所以首先确定是否还有存储空间,若有,则根据原线性表中元素的有序性,来确定插入元素的插入位置,后面的元素为它让出位置,(也可以从高下标端开始一边比较,一边移位)然后插入x,最后修改表示表长的变量。
intinsert(datatypea[],int*elenum,datatypex)/*设elenum为表的最大下标*/{if(*elenum==arrsize-1)return0;/*表已满,无法插入*/
else{i=*elenum;
while(i=0a[i]x)/*边找位置边移动*/
{a[i+1]=a[i];
i--;
}
a[i+1]=x;/*找到的位置是插入位的下一位*/(*elenum)++;
return1;/*插入成功*/
}
}
时间复杂度为o(n)。
2.已知一顺序表a,其元素值非递减有序排列,编写一个算法删除顺序表中多余的值相同的元素。
【提示】对顺序表a,从第一个元素开始,查找其后和之值相同的所有元素,将它们删除;再对第二个元素做同样处理,依此类推。
voiddelete(seqlist*a)
{i=0;
while(ia-last)/*将第i个元素以后和其值相同的元素删除*/
{k=i+1;
while(k=a-lasta-data[i]==a-data[k])
k++;/*使k指向第一个和a[i]不同的元素*/n=k-i-1;/*n表示要删除元素的个数*/
for(j=k;j=a-last;j++)
a-data[j-n]=a-data[j];/*删除多余元素*/
a-last=a-last-n;
i++;
}
}
3.写一个算法,从一个给定的顺序表a中删除值在x~y(x=y)之间的所有元素,要求以较高的效率来实现。
【提示】对顺序表a,从前向后依次判断当前元素a-data[i]是否介于x和y之间,若是,并不立即删除,而是用n记录删除时应前移元素的位移量;若不是,则将a-data[i]向前移动n位。
n用来记录当前已删除元素的个数。
voiddelete(seqlist*a,intx,inty)
{i=0;
n=0;
while(ia-last)
{if(a-data[i]=xa-data[i]=y)n++;/*若a-data[i]介于x和y之间,n自增*/elsea-data[i-n]=a-data[i];/*否则向前移动a-data[i]*/
i++;
}
a-last-=n;
}
4.线性表中有n个元素,每个元素是一个字符,现存于向量r[n]中,试写一算法,使r中的字符按字母字符、数字字符和其它字符的顺序排列。
要求利用原来的存储空间,元素移动次数最小。
【提示】对线性表进行两次扫描,第一次将所有的字母放在前面,第二次将所有的数字放在字母之后,其它字符之前。
intfch(charc)/*判断c是否字母*/
{if(c=ac=z||c=ac=z)return
(1);
elsereturn(0);
}
intfnum(charc)/*判断c是否数字*/
{if(c=0c=9)return
(1);
elsereturn(0);
}
voidprocess(charr[n])
{low=0;
high=n-1;
while(lowhigh)/*将字母放在前面*/
{while(lowhighfch(r[low]))low++;
while(lowhigh!
fch(r[high]))high--;
if(lowhigh)
{k=r[low];
r[low]=r[high];
r[high]=k;
}
}
low=low+1;
high=n-1;
while(lowhigh)/*将数字放在字母后面,其它字符前面*/{while(lowhighfnum(r[low]))low++;
while(lowhigh!
fnum(r[high]))high--;
if(lowhigh)
{k=r[low];
r[low]=r[high];
r[high]=k;
}
}
}
5.线性表用顺序存储,设计一个算法,用尽可能少的辅助存储空间将顺序表中前m个元素和后n个元素进行整体互换。
即将线性表:
(a1,a2,…,am,b1,b2,…,bn)改变为:
(b1,b2,…,bn,a1,a2,…,am)。
【提示】比较m和n的大小,若mn,则将表中元素依次前移m次;否则,将表中元素依次后移n次。
voidprocess(seqlist*l,intm,intn)
{if(m=n)
for(i=1;i=m;i++)
{x=l-data[0];
for(k=1;k=l-last;k++)
l-data[k-1]=l-data[k];
l-data[l-last]=x;
}
elsefor(i=1;i=n;i++)
{x=l-data[l-last];
for(k=l-last-1;k=0;k--)
l-data[k+1]=l-data[k];
l-data[0]=x;}
}
6.已知带头结点的单链表l中的结点是按整数值递增排列的,试写一算法,将值为x的结点插入到表l中,使得l仍然递增有序,并且分析算法的时间复杂度。
linklistinsert(linklistl,intx)
{p=l;
while(p-nextxp-next-data)
p=p-next;/*寻找插入位置*/s=(lnode*)malloc(sizeof(lnode));/*申请结点空间*/s-data=x;/*填装结点*/
s-next=p-next;
p-next=s;/*将结点插入到链表中*/return(l);
}
7.假设有两个已排序(递增)的单链表a和b,编写算法将它们合并成一个链表c而不改变其排序性。
linklistcombine(linklista,linklistb)
{c=a;
rc=c;
pa=a-next;/*pa指向表a的第一个结点*/
pb=b-next;/*pb指向表b的第一个结点*/
free(b);/*释放b的头结点*/
while(papb)/*将pa、pb所指向结点中,值较小的一个插入到链表c的表尾*/if(pa-datapb-data)
{rc-next=pa;
rc=pa;
pa=pa-next;
}
else
{rc-next=pb;
rc=pb;
pb=pb-next;
}
if(pa)rc-next=pa;
elserc-next=pb;/*将链表a或b中剩余的部分链接到链表c的表尾*/
return(c);
}
8.假设长度大于1的循环单链表中,既无头结点也无头指针,p为指向该链表中某一结点的指针,编写算法删除该结点的前驱结点。
【提示】利用循环单链表的特点,通过s指针可循环找到其前驱结点p及p的前驱结点q,然后可删除结点*p。
vioddelepre(lnode*s)
{lnode*p,*q;
p=s;
while(p-next!
=s)
{q=p;
p=p-next;
}
q-next=s;
free(p);
}
9.已知两个单链表a和b分别表示两个集合,其元素递增排列,编写算法求出a和b的交集c,要求c同样以元素递增的单链表形式存储。
【提示】交集指的是两个单链表的元素值相同的结点的集合,为了操作方便,先让单链表c带有一个头结点,最后将其删除掉。
算法中指针p用来指向a中的当前结点,指针q用来指向b中的当前结点,将其值进行比较,两者相等时,属于交集中的一个元素,两者不等时,将其较小者跳过,继续后面的比较。
linklistintersect(linklista,linklistb)
{lnode*q,*p,*r,*s;
linklistc;
c=(lnode*)malloc(sizeof(lnode));
c-next=null;
r=c;
p=a;
q=b;
while(pq)
if(p-dataq-data)p=p-next;
elseif(p-data==q-data)
{s=(lnode*)malloc(sizeof(lnode));
s-data=p-data;
r-next=s;
r=s;
p=p-next;
q=q-next;
}
elseq=q-next;
r-next=null;
c=c-next;
returnc;
}
10.设有一个双向链表,每个结点中除有prior、data和next域外,还有一个访问频度freq域,在链表被起用之前,该域的值初始化为零。
每当在链表进行一次locata(l,x)运算后,令值为x的结点中的freq域增1,并调整表中结点的次序,使其按访问频度的非递增序列排列,以便使频繁访问的结点总是靠近表头。
试写一个满足上述要求的locata(l,x)算法。
【提示】在定位操作的同时,需要调整链表中结点的次序:
每次进行定位操作后,要查看所查找结点的freq域,将其同前面结点的freq域进行比较,同时进行结点次序的调整。
typedefstructdnode
【篇二:
数据结构课后习题答案】
lass=txt>高等学校精品资源共享课程
绪论
第1章
1.1什么是数据结构?
【答】:
数据结构是指按一定的逻辑结构组成的一批数据,使用某种存储结构将这批数据存储于计算机中,并在这些数据上定义了一个运算集合。
1.2数据结构涉及哪几个方面?
【答】:
数据结构涉及三个方面的内容,即数据的逻辑结构、数据的存储结构和数据的运算集合。
1.3两个数据结构的逻辑结构和存储结构都相同,但是它们的运算集合中有一个运算的定义不一样,它们是否可以认作是同一个数据结构?
为什么?
【答】:
不能,运算集合是数据结构的重要组成部分,不同的运算集合所确定的数据结构是不一样的,例如,栈和队列它们的逻辑结构和存储结构可以相同,但由于它们的运算集合不一样,所以它们是两种不同的数据结构。
1.4线性结构的特点是什么?
非线性结构的特点是什么?
【答】:
线性结构元素之间的关系是一对一的,在线性结构中只有一个开始结点和一个终端结点,其他的每一个结点有且仅有一个前驱和一个后继结点。
而非线性结构则没有这个特点,元素之间的关系可以是一对多的或多对多的。
1.5数据结构的存储方式有哪几种?
【答】:
数据结构的存储方式有顺序存储、链式存储、散列存储和索引存储等四种方式。
1.6算法有哪些特点?
它和程序的主要区别是什么?
【答】:
算法具有
(1)有穷性
(2)确定性(3)0个或多个输入(4)1个或多个输出(5)可行性等特征。
程序是算法的一种描述方式,通过程序可以在计算机上实现算法。
1.7抽象数据类型的是什么?
它有什么特点?
【答】:
抽象数据类型是数据类型的进一步抽象,是大家熟知的基本数据类型的延伸和发展。
抽象数据类型是和表示无关的数据类型,是一个数据模型及定义在该模型上的一组运算。
对一个抽象数据类型进行定义时,必须给出它的名字及各运算的运算符名,即函数名,并且规定这些函数的参数性质。
一旦定义了一个抽象数据类型及具体实现,程序设计中就可以像使用基本数据类型那样,十分方便地使用抽象数据类型。
抽象数据类型的设计者根据这些描述给出操作的具体实现,抽象数据类型的使用者依据这些描述使用抽象数据类型。
1.8算法的时间复杂度指的是什么?
如何表示?
【答】:
算法执行时间的度量不是采用算法执行的绝对时间来计算的,因为一个算法在不同的机器上执行所花的时间不一样,在不同时刻也会由于计算机资源占用情况的不同,使得算法在同一台计算机上执行的时间也不一样,另外,算法执行的时间还和输入数据的状态有关,所以对于算法的时间复杂性,采用算法执行过程中其基本操作的执行次数,称为计算量来度量。
算法中基本操作的执行次数一般是和问题规模有关的,对于结点个数为n的数据处理问题,用t(n)表示算法基本操作的执行次数。
为了评价算法的执行效率,通常采用大写o符号表示算法的时间复杂度,大写o符号给出了函数f的一个上限。
其它义如下:
3
十二五普通高等教育国家级本科规划教材
高等学校精品资源共享课程
定义:
f(n)=o(g(n))当且仅当存在正的常数c和n0,使得对于所有的n≥n0,有f(n)≤cg(n)。
上述定义表明,函数f顶多是函数g的c倍,除非n小于n0。
因此对于足够大的n(如n≥n0),g是f的一个上限(不考虑常数因子c)。
在为函数f提供一个上限函数g时,通常使用比较简单的函数形式。
比较典型的形式是含有n的单个项(带一个常数系数)。
表1-1列出了一些常用的g函数及其名称。
对于表1-1中的对数函数logn,没有给出对数基,原因是对于任何大于1的常数a和b都有logan=logbn/logba,所以logan和logbn都有一个相对的乘法系数1/logba,其中a是一个常量。
表1-1常用的渐进函数
1.9【答】:
算法的空间复杂度是指算法在执行过程中占用的额外的辅助空间的个数。
可以将它表
示为问题规模的函数,并通过大写o符号表示空间复杂度。
1.10对于下面的程序段,分析带下划线的语句的执行次数,并给出它们的时间复杂度t(n)。
(1)i++;
(2)for(i=0;in;i++)
if(a[i]x)x=a[i];
(3)for(i=0;in;i++)
for(j=0;jn;j++)
;
(4)for(i=1;i=n-1;i++)
{k=i;
for(j=i+1;j=n;j++)
if(a[j]a[j+1])k=j;t=a[k];a[k]=a[i];a[i]=t;}
(5)for(i=0;in;i++)
for(j=0;jn;j++)
{++x;s=s+x;}
【答】:
(1)o
(1);
(2)o(n);(3)o(n2);(4)o(n2);(5)o(n2)
4
第2章线性表及其顺序存储
2.1选择题
(1)表长为n的顺序存储的线性表,当在任何位置上插入或删除一个元素的概率相等时,插入一个元素所需移动元素的平均个数为(为(a)。
a.(n?
1)/2e.n/2
b.nf.(n+1)/2
c.n+1
d.n?
1
g.(n?
2)/2
(2)设栈s和队列q的初始状态为空,元素e1、e2、e3、e4、e5和e6依次通过栈s,一个元素出栈后即进入队列q,若6个元素出队的序列为e2、e4、e3、e6、e5和e1,则栈s的容量至少应该为(c)。
a.6
(b)。
a.不确定
b.n?
i+1
c.i
d.n?
i
(4)在一个长度为n的顺序表中删除第i个元素(1=i=n)时,需向前移动(a)个元素。
a.n?
i
间复杂度为(a)。
a.o(n)
b.o
(1)
c.o(n2)
)。
d.?
+*abcdd.o(n3)
(6)表达式a*(b+c)?
d的后缀表达式是(b
b.n?
i+1
c.n?
i?
1
d.i
(5)若长度为n的线性表采用顺序存储结构存储,在第i个位置上插入一个新元素的时
b.4
c.3
d.2
(3)设栈的输入序列为1、2、3…n,若输出序列的第一个元素为n,则第i个输出的元素为
e),删除一个元素所需移动元素的平均个数
a.abcd*+?
b.abc+*d?
c.abc*+d?
(7)队列是一种特殊的线性表,其特殊性在于(c)。
a.插入和删除在表的不同位置执行b.插入和删除在表的两端位置执行c.插入和删除分别在表的两端执行d.插入和删除都在表的某一端执行(8)栈是一种特殊的线性表,具有(b)性质。
a.先进先出
b.先进后出
c.后进后出
d.顺序进出
(9)顺序循环队列中(数组的大小为n),队头指示front指向队列的第1个元素,队尾指示rear指向队列最后元素的后1个位置,则循环队列中存放了n?
?
?
1个元素,即循环队列满
)。
的条件为(b
a.(rear+1)%n=front?
1c.(rear)%n=front
b.(rear+1)%n=frontd.rear+1=front
(10)顺序循环队列中(数组的大小为6),队头指示front和队尾指示rear的值分别为3和0,当从队列中删除1个元素,再插入2个元素后,front和rear的值分别为(d)。
a.5和1
b.2和4
c.1和5
d.4和2
2.2什么是顺序表?
什么是栈?
什么是队列?
5
【答】:
当线性表采用顺序存储结构时,即为顺序表。
栈是一种特殊的线性表,它的特殊性表现在约定了在这种线性表中数据的插入和删除操作只能在这种线性表的同一端进行(即栈顶),因此,栈具有先进后出、后进先出的特点。
队列也是一种特殊的线性表,它的特殊性表现在约定了在这种线性表中数据的插入在表的一端进行,数据的删除在表的另一端进行,因此队列具有先进先出,后进后出的特点。
2.3设计一个算法,求顺序表中值为x的结点的个数。
【答】:
顺序表的存储结构定义如下(文件名seqlist.h):
#includestdio.h#definen100typedefintdatatype;typedefstruct{
datatypedata[n];intlength;}seqlist;
/*预定义最大的数据域空间*//*假设数据类型为整型*/
/*此处假设数据元素只包含一个整型的关键字域*//*线性表长度*/
/*预定义的顺序表类型*/
算法countx(l,x)用于求顺序表l中值为x的结点的个数。
intcountx(seqlist*l,datatypex){
intc=0;inti;
for(i=0;il-length;i++)
if(l-data[i]==x)c++;returnc;}
2.4设计一个算法,将一个顺序表倒置。
即,如果顺序表各个结点值存储在一维数组a中,倒置的结果是使得数组a中的a[0]等于原来的最后一个元素,a[1]等于原来的倒数第2个元素,…,a的最后一个元素等于原来的第一个元素。
【答】:
顺序表的存储结构定义同题2.3,实现顺序表倒置的算法程序如下:
voidverge(seqlist*l){intt,i,j;i=0;
j=l-length-1;while(ij)
{t=l-data[i];
l-data[i++]=l-data[j];l-data[j--]=t;}}
2.5已知一个顺序表中的各结点值是从小到大有序的,设计一个算法,插入一个值为x的结点,使顺序表中的结点仍然是从小到大有序。
【答】:
顺序表的定义同题2.3,实现本题要求的算法程序如下:
6
voidinsertx(seqlist*l,datatypex){intj;
if(l-lengthn){j=l-length-1;
while(j=0l-data[j]x)
{l-data[j+1]=l-data[j];
j--;}l-data[j+1]=x;l-length++;}}
2.6将下列中缀表达式转换为等价的后缀表达式。
(1)5+6*7
(2)(5-6)/7(3)5-6*7*8(4)5*7-8(5)5*(7-6)+8/9(6)7*(5-6*8)-9【答】:
(7)5+6*7(8)(5-6)/7(9)5-6*7*8(10)5*7-8(11)5*(7-6)+8/9(12)7*(5-6*8)-9
后缀表达式:
567*+后缀表达式:
56-7/后缀表达式:
567*8*-后缀表达式:
57*8-后缀表达式:
576-*89/+后缀表达式:
7568*-*9-
2.7循环队列存储在一个数组中,数组大小为n,队首指针和队尾指针分别为front和rear,请写出求循环队列中当前结点个数的表达式。
【答】:
循环队列中当前结点个数的计算公式是:
(n+rear-front)%n
2.8编号为1,2,3,4的四列火车通过一个栈式的列车调度站,可能得到的调度结果有哪些?
如果有n列火车通过调度站,请设计一个算法,输出所有可能的调度结果。
【答】:
方法一:
算法思想:
逐次输出所有可能,用回溯法。
即:
总体:
对原始序列中的每一个元素,总是先入栈,后出栈
1.入栈后的操作:
a.该元素出栈;b.下一个元素入栈;
2.出栈后的操作:
a.(栈中其他元素)继续出栈;b.(原始序列中)下一个数入栈;注意:
回溯法,关键在于回溯,即在某分支结点x:
处理x的一个子分支,再退回分支x,接着处理x的下一个子分支,若所有x的子分支处理完,再退回上一层分支节点。
所谓“退回”,
7
【篇三:
数据结构课后习题答案】
下列概念:
数据、数据元素、数据项、数据对象、数据结构、逻辑结构、存储结构、抽象数据类型。
答案:
数据:
是客观事物的符号表示,指所有能输入到计算机中并被计算机程序处理的符号的总称。
如数学计算中用到的整数和实数,文本编辑所用到的字符串