习 题 答 案
第1章参考答案
一、填空题
1. 数据元素的有限集,犇 中数据元素之间客观存在的关系的有限集
2. 顺序存储结构,链式存储结构,散列存储结构
3.犗(犿狀)
4.犗(狀)
5.犗(log3狀)
二、选择题
1.C 2.D 3.B 4.C,A 5.C
三、简答题
1. 数据结构就是带有结构的数据的集合,包括数据元素、 元素之间的 关系 和对 数据 元素的 操
作3个部分;逻辑结构包括线性表、栈、队列、树、二叉树、无向 图、有 向图 等,结 构 特
征即元素之间的关系。
2.5个特点:1)有穷性;2) 确定性;3)可行性;4) 输入;5)输出。
2个区别:1)有穷性;2) 描述方法。
3. 设犳犪犮狋(狀)的运行时间函数是犜(狀)。该函数中语句①的运行时 间是犗(1), 语 句②的运 行
时间是犜(狀-1)+犗(1),其中犗(1) 为运行时间。因此:
则:
犜(狀)=
犗(1) 狀≤1
犜(狀-1)+犗(1) 狀>
1
{
犜(狀)=犗(1)+犜(狀-1)
=2犗(1)+犜(狀-2)
…
=(狀-1)犗(1)+犜(1)
=狀犗(1)
=犗(狀)
即犳犪犮狋(狀)的时间复杂度为犗(狀)。
四、算法设计题
1. 算法描述1(自然语言描述):
步骤1:输入要查找的学生姓名 StuName。
步骤2:将该班级名册中的第一个学生作为当前学生。
步骤3:将当前学生的 姓 名 与 StuName进 行 比 较, 如 果 相 符, 则 输 出 “yes”, 表 示 找 到,
算法结束;否则,执行步骤4。
步骤4:如果当前学生不是该班最后一 个 学 生, 则 取 下 一 个 学 生 作 为 当 前 学 生, 执 行 步 骤
2;否则,输出 “no”,表示没有找到,算法结束。
2
算法描述2(框图描述):
习 题 答 案
2.犻狀狋狊狌犿(犃){
犻狀狋犻,狊狋犪狉狋,犲狀犱,狊=0;
狊犮犪狀犳("%犱",狊狋犪狉狋);
狊犮犪狀犳("%犱",犲狀犱);
犳狅狉(犻=狊狋犪狉狋+1;犻 犲狀犱;犻++)
狊=狊+犃[犻];
狉犲狋狌狉狀狊;}
3.
第2章参考答案
一、选择题
1.C 2.D 3.C 4.C 5.B 6.A 7.A 8.B 9.C 10.D
习 题 答 案
二、填空题
1.狀/2,(狀-1)/2
2. 顺序,链式
3. 将犾犻狊狋改为指向第二个结点,然后释放第一个结点的空间
4. 线性链表 (单链表),循环链表,双向链表,线性链表 (单链表)
3
5.8
6.489
7.犳狉狅狀狋==狉犲犪狉
8.狀-1
9. 逻辑顺序,物理顺序
10.犎犛==犖犝犔犔
三、简答题
1. 开始结点是指链表中的第一个结点,也就是没有直接前趋的那个结点。
链表的头指针是一指向链表开始结点的指针 (没有头结点时), 单链 表由 头指 针唯 一确 定,
因此单链表可以用头指针的名字来命名。
头结点是我们人为地在链表的开始结点之前附加的一个结点。有了 头结 点之 后,头 指针指
向头结点,不论链表否为空,头指针总是非空。而且头指针的设 置 使 得 对 链 表 的 第 一 个 位
置上的操作与对表的其他位置上的操作一致 (都是在某一结点之后)。
2. 若频繁地对线性表进行插入和删除操作,该线性表应采用链式存储 的方 式。因 为若 采用顺
序存储,在插入或删除元素时,要频繁地移动元素的 位置,从而使得 时间 效率变 低,而 链
式存储由于只需修改指针,能很好地克服这一缺陷。
3. 对于上三角矩阵,存储思想是常量存放在第一个位置, 其他元素以 列为 主序 顺序 存储上 三
角部分。对于狀×狀的上三角矩阵,由于犪犻犼的前面有犼-1列,其中第1列有1个 元素, 第
2列有2个元素,……,第犼-1列有 (犼-1) 个元素,又第犼列前 面有 (犻-1) 个 数 据 元
素,再加上第一个单元的常数,其前面共有 1+2+ … +犼-1+犻-1+1=犼(犼-1)/2+犻个
元素,则狊犪[犽]与犪犻犼的对应关系为:犽=犼(犼-1)/2+犻(犻≤犼),犽=0(犻>犼)。
4. 循环队列的优点是:它可以克服顺序队列的 “假上溢” 现象,能 够使 存储 队列 的向 量空间
得到充分的利用。判别循环队列的 “空”或 “满” 不能以头 尾 指 针 是 否 相 等 来 确 定, 一 般
是通过以下几种方法:一是另设一布尔变量来区别队列的空和满;二 是少 用一 个元 素的空
间,每次入队前测试入队后头尾指针是否会重合,如果会重 合 就 认 为 队 列 已 满;三 是 设 置
一计数器记录队列中的元素总数,这不仅可判别空或满,还可以得到队列中元素的个数。
5.1)IIIOOOIOIO
2)IOIIOOIIOO
四、算法设计题
1. 因已知顺序表犔是非递减有序表,所以只要从头开始找到第一个比它大 (或相 等) 的结 点
数据,把狓插入到这个数据所在的位置就可以了。算法如下:
狏狅犻犱犐狀狊犲狉狋犐狀犮狉犲犪狊犲犔犻狊狋(犛狇犾犻狊狋犔 ,犇犪狋犪狋狔狆犲狓 ){
犻狀狋犻;
犳狅狉(犻=0 ;犻 犔 犾犲狀犵狋犺牔牔犔 犱犪狋犪[犻 ] 狓 ;犻++);// 查找并比较,分号不能少
4
习 题 答 案
犐狀狊犲狉狋犔犻狊狋(犔 ,狓 ,犻 );// 调用顺序表插入函数
}
2. 所谓逆转一个线性链表,是指在不增加新的链结点空间的前提下,依 次改 变链 表中 链结点
的链接方向,即链表第一个链结点成为链表的最末端的那个结点,最 末端 那个 结点 成为链
表的第一个结点,第二个结点成为倒数第二个结点,依次类推。算法如下:
狏狅犻犱犐狀狏犲狉狋(犔犻狊狋犔){
狆=犔犾犻狊狋; //变量 狆首先指向链表的第一个结点
狇=狀狌犾犾;
狑犺犻犾犲(狆!=狀狌犾犾) //交互对应结点位置,直至列表末端
犱狅{
狉=狇;
狇=狆;
狆=狆狀犲狓狋;
狇狀犲狓狋=狉;
}
犔犾犻狊狋=狇
}
3. 犛犘犕犪狋狉犻狓犜狉犪狀狊犕2(犛犘犕犪狋狉犻狓犃){
犛犘犕犪狋狉犻狓犅;
犻狀狋犻,犼,犽;
犻狀狋狀狌犿[犃 狀狌+1],犮狆狅狋[犃 狀狌+1];
犅=狀犲狑犛犘犕犪狋狉犻狓;
犅 犿狌=犃 狀狌;
犅 狀狌=犃 犿狌 ;
犅 狋狌=犃 狋狌;
犻犳(犅 狋狌 0)
{ 犳狅狉(犻=1;犻 = 犃 狀狌;犻++) 狀狌犿[犻]=0;
犳狅狉(犻=1;犻 犃 狀狌;犻++)
{ 犼=犃 犱犪狋犪[犻]犼;
狀狌犿[犼]++;
}
犮狆狅狋[1]=1;
犳狅狉(犻=2;犻 =犃 狀狌;犻++)
犮狆狅狋[犻]=犮狆狅狋[犻-1]+狀狌犿[犻-1];
犳狅狉(犻=1;犻 = 犃 狋狌;犻++)
{ 犼=犃 犱犪狋犪[犻]犼;
犽=犮狆狅狋[犼];
犅 犱犪狋犪[犽]犻= 犃 犱犪狋犪[犻]犼;
犅 犱犪狋犪[犽]犼= 犃 犱犪狋犪[犻]犻;
犅 犱犪狋犪[犽]狏= 犃 犱犪狋犪[犻]狏;
犮狆狅狋[犼]++;
}}
狉犲狋狌狉狀犅;}
4. 知道了尾指针和元素个数,当然就能知道队头元素了。算法如下:
犻狀狋犉狌犾犾犙狌犲狌犲(犆犻狉犙狌犲狌犲犙)
{
习 题 答 案
5
//判队满,队中元素个数等于空间大小
狉犲狋狌狉狀犙 狇狌犲犾犲狀==犙狌犲狌犲犛犻狕犲;
}
狏狅犻犱犈狀犙狌犲狌犲(犆犻狉犙狌犲狌犲犙,犇犪狋犪狋狔狆犲狓)
{
// 入队
犻犳(犉狌犾犾犙狌犲狌犲(犙)){
犈狉狉狅狉("队已满,无法入队");
犲狓犻狋(0);
}
犙 犇犪狋犪[犙 狉犲犪狉]=狓;
犙 狉犲犪狉=(犙 狉犲犪狉+1)%犙狌犲狌犲犛犻狕犲;//在循环意义上的加1
犙 狇狌犲犾犲狀++;
}
犇犪狋犪狋狔狆犲犇犲犙狌犲狌犲(犆犻狉犙狌犲狌犲犙)
{
//出队
犻犳(犙 狇狌犲犾犲狀==0){
犈狉狉狅狉("队已空,无元素可出队");
犲狓犻狋(0);
}
犻狀狋狋犿狆犳狉狅狀狋;//设一个临时队头指针
犻犳(犙 狉犲犪狉 犙 狇狌犲犾犲狀)//计算头指针位置
狋犿狆犳狉狅狀狋=犙 狉犲犪狉 - 犙 狇狌犲犾犲狀;
犲犾狊犲
狋犿狆犳狉狅狀狋=犙 狉犲犪狉 + 犙狌犲狌犲犛犻狕犲 - 犙 狇狌犲犾犲狀;
狇狌犲犾犲狀--;
狉犲狋狌狉狀犙 犇犪狋犪[狋犿狆犳狉狅狀狋];
}
5. #犻狀犮犾狌犱犲"犻狅狊狋狉犲犪犿犺"
犮狅狀狊狋犻狀狋狀0=30;
犻狀狋狊1[狀0+1];//操作数栈
犮犺犪狉狊2[狀0+1];//运算符栈
犻狀狋狋1,狋2;
犻狀狋狀狌犿[4];//提取表达式中的整数
狏狅犻犱犮犪犾犮狌(){
犻狀狋狓1,狓2,狓;
犮犺犪狉狆;
//弹出一个运算符
狆=狊2[狋2--];
//弹出两个操作数
狓2=狊1[狋1--];
狓1=狊1[狋1--];
//进行一次运算
狊狑犻狋犮犺(狆){
6
习 题 答 案
犮犪狊犲 +
:狓=狓1+狓2;犫狉犲犪犽;
犮犪狊犲 -
:狓=狓1-狓2;犫狉犲犪犽;
犮犪狊犲
犮犪狊犲
}
:狓=狓1狓2;犫狉犲犪犽;
:狓=狓1/狓2;
/
//结果压入操作数栈
狊1[++狋1]=狓;}
犻狀狋犮犪犾犮狌犾犪狋狅狉(犮犺犪狉犳){
犻狀狋狏,犻=0;
犮犺犪狉狆=犳;
狋1=狋2=0;//设置空栈
狑犺犻犾犲(狆!= \0
狊狑犻狋犮犺(狆){
){
:
:犮犪狊犲 -
(
))
犮犪狊犲 +
狑犺犻犾犲(狋2牔牔(狊2[狋2]!=
//执行先遇到的加、减、乘、除运算
犮犪犾犮狌();
//当前运算符入栈
狊2[++狋2]=狆;
//读下一个字符
狆++;
犫狉犲犪犽;
)||(狊2[狋2]==
/
))
:
:犮犪狊犲
/
犮犪狊犲
犻犳(狋2牔牔(狊2[狋2]==
//执行先遇到的乘、除运算
犮犪犾犮狌();
//当前运算符入栈
狊2[++狋2]=狆;
//读下一个字符
狆++;
犫狉犲犪犽;
(
:
犮犪狊犲
//左括号入栈
狊2[++狋2]=狆;
//读下一个字符
狆++;
犫狉犲犪犽;
:
)
)
(
犮犪狊犲
狑犺犻犾犲(狊2[狋2]!=
//执行括号内的加、减、乘、除运算
犮犪犾犮狌();
//弹出左括号
狋2--;
//读下一个字符
狆++;
犫狉犲犪犽;
习 题 答 案
犱犲犳犪狌犾狋:
//把字符串转换成整数值
狏=0;
犱狅 {
狏=10狏+狆- 0
;
狆++;
7
}狑犺犻犾犲((狆 = 0
)牔牔(狆 = 9
));
//操作数入栈
狊1[++狋1]=狏;
狀狌犿[犻++]=狏;
}
}
//执行先遇到的加、减、乘、除运算
狑犺犻犾犲(狋2)犮犪犾犮狌();
//返回结果
狉犲狋狌狉狀狊1[狋1];
}
狏狅犻犱犿犪犻狀()
{
犮犺犪狉犪[]="5(40+6)-39";
犮狅狌狋 犮犪犾犮狌犾犪狋狅狉(犪) 犲狀犱犾;
犮狅狌狋 "其中的数字为:\狀";
犳狅狉(犻狀狋犻=0;犻 4;犻++)
{
犮狅狌狋 狀狌犿[犻] ";
}
犮狅狌狋 犲狀犱犾;
}
第3章参考答案
一、选择题
1.B 2.C 3.A 4.D 5.D 6.B 7.A 8.A 9.C 10.D
二、填空题
1.狆 犳犻狉狊狋犮犺犻犾犱==犖犝犔犔
2.3犺-1
3.6,261
4.5
5.3,6
6.10,1023
7. 叶子结点的相对次序不发生改变
8.++犪犫34-犮犱,18
9.狊狋犪犮犽[狋狆]=狋;,狆=狊狋犪犮犽[狋狆--];,狆;,++狋狆
10.0,犺犾 犺狉,犺狉=犺犾
8
三、简答题
1.1)犓犺-1(犺为层数)。
习 题 答 案
2) 因为该树每层上均有 犓犺-1个结点,从根开始编号为1,则结点犻的从右向左数第2个孩
子的结点编号为 犓×犻。设狀为结点犻的子女,则 关 系 式 (犻-1)×犓+2≤狀≤犻×犓+1
成立,因犻是整数,故结点狀的双亲犻的编号为狀-2)/犓 +1。
3)结点狀(狀 1) 的前一结点编号为狀-1(其最右边子女编号是 (狀-1)犓+1),故结点狀
的第犻个孩子的编号是 (狀-1)犓+1+犻。
4) 根 据 以 上 分 析 , 结 点狀有 右 兄 弟 的 条 件 是 : 它 不 是 双 亲 的 从 右 数 的 第 一 个 子 女 , 即
(狀-1)%犓! =0, 其 右 兄 弟 编 号 是狀+1。
2. 设树的结点数为狀,分支数为犅,则下面两式成立:
狀=狀0 +狀1 +狀2 + … +狀犿
狀=犅+1=狀1 +2狀2 + … +犿狀犿
(1)
(2)
由 (1)和 (2),可得狀0=狀2+2狀3+…+(犿-1)狀犿。
5.
四、算法设计题
1. 由指示结点犻左儿子和右儿子的两个一维数组犔[犻] 和 犚[犻],很 容 易 建 立 指 示 结 点犻的 双
亲的一维数组犜[犻],根据犜 数组,判断结点犝 是否是结点犞 后代 的算 法,转 为判 断结点
犞 是否是结点犝 的祖先的问题。
犻狀狋犌犲狀犲狉犪狋犻狅狀(犻狀狋犝,犞,犖,犔[],犚[],犜[]){
//犔[]和 犚[]是含有 犖个元素且指示二叉树结点 犻左儿子和右儿子的一维数组,
//本算法据此建立结点 犻的双亲数组 犜,并判断结点 犝是否是结点 犞的后代。
犳狅狉(犻=1;犻 =犖;犻++)犜[犻]=0; //犜数组初始化