DS博客作业07--查找
1.本周学习总结
1.1思维导图
1.2.谈谈你对查找运算的认识及学习体会。
本周对查找的相关知识进行了系统地学习。经历了顺序表的查找、树表的查找和哈希表的查找。顺序表的查找中,学习了顺序查找、折半查找、索引存储结构和分块查找。树表的查找学习得比较深入,先时学习了二叉排序树与平衡二叉树,后又拓展性地学习了B-树和B+树,个人认为这里相对于之前学得所有内容来说会复杂一些,尤其是平衡二叉树插入的调整、B-树结点的插入与删除。哈希表的查找就相对要简单些。有了以前的一些的积累,哈希表的使用要相对轻松些。在原有的基础上补充了哈希冲突的相关问题,学习了解决哈希冲突的一些方法,如线性探测法、拉链法。
2.PTA实验作业
2.1题目1:6-3 二叉搜索树中的最近公共祖先 (25 分)
在一棵树T中两个结点u和v的最近公共祖先(LCA),是树中以u和v为其后代的深度最大的那个结点。现给定某二叉搜索树(BST)中任意两个结点,要求你找出它们的最近公共祖先。
2.1.1设计思路
/*函数题*/
定义flag1判断u是否在树中,flag2判断v是否在树中(初始化0),定义index为下标
Tree类型 指针p,que队列(用于层次遍历)
if 空 then
return ERROR
end if
根节点入队
while 队不空 do
p指向队首
if 找到u then
flag1 = 1
end if
if 找到v then
flag2 = 1
end if
if p有左孩子 then
左孩子入队
end if
if p有右孩子 then
右孩子入队
end if
end while
if u和v都在树中
情况1 先到达u或v 当前结点为最近祖先结点
情况2 u左v右或u右v左 当前结点为最近祖先结点
情况3 u大于当前key 递归右子树
情况4 u小于当前key 递归左子树
else
return ERROR
2.1.2代码截图
2.1.3本题PTA提交列表说明。
- Q:处理判断u和v是否在树中的方法不当。一开始我的想法是在用递归来判断u和v是否在树中,但因为是函数题,缺少全局变量的支持,所以一直没有解决。后来上课听了老师的方法(单独用一个find函数来递归实现查找u和v),但却不适用于这题(函数题)。后来在自由时间突然灵光一闪,可以采用层次遍历来做到查找。当然因为是函数题无法用que容器,就用数组+下标的方法解决了这个问题。
2.2题目2:7-1 QQ帐户的申请与登陆 (25 分)
输入格式:
输入首先给出一个正整数N(≤10
5
),随后给出N行指令。每行指令的格式为:“命令符(空格)QQ号码(空格)密码”。其中命令符为“N”(代表New)时表示要新申请一个QQ号,后面是新帐户的号码和密码;命令符为“L”(代表Login)时表示是老帐户登陆,后面是登陆信息。QQ号码为一个不超过10位、但大于1000(据说QQ老总的号码是1001)的整数。密码为不小于6位、不超过16位、且不包含空格的字符串。
输出格式:
针对每条指令,给出相应的信息:1)若新申请帐户成功,则输出“New: OK”;2)若新申请的号码已经存在,则输出“ERROR: Exist”;3)若老帐户登陆成功,则输出“Login: OK”;4)若老帐户QQ号码不存在,则输出“ERROR: Not Exist”;5)若老帐户密码错误,则输出“ERROR: Wrong PW”。
2.2.1设计思路
/*map最简单用法*/
定义n存放次数 字符ope存放操作字符 字符串a,b分别为QQ账号以及密码
定义map容器QQ
输入n
while n-- do
输入ope
if 操作为申请 then
输入账号密码
用是否存在键值对判断是否已经有该账号
if 该账号已经存在 then
输出ERROR:Exist
else
创建a-b键值对
输出NEW:OK
end if
else if 操作为登入 then
输入a、b
if 该账号已经存在 then
if 键值对正确匹配 then
输出Login:OK
else
输出ERROR:Wrong PW
else //该账号不存在
输出ERROR:Not Exist
end if
end while
2.2.2代码截图
2.2.3本题PTA提交列表说明。
- Q:一开始在写代码的时候map查找的判断式子写错了。后来测试数据对了就交上去,忘记改c++编译了......然后交上去不会对,过了一会儿没找到问题...多交几次居然就对了。
2.3题目3:7-2 航空公司VIP客户查询 (25 分)
不少航空公司都会提供优惠的会员服务,当某顾客飞行里程累积达到一定数量后,可以使用里程积分直接兑换奖励机票或奖励升舱等服务。现给定某航空公司全体会员的飞行记录,要求实现根据身份证号码快速查询会员里程积分的功能。输入首先给出两个正整数N(≤105)和K(≤500)。其中K是最低里程,即为照顾乘坐短程航班的会员,航空公司还会将航程低于K公里的航班也按K公里累积。随后N行,每行给出一条飞行记录。飞行记录的输入格式为:18位身份证号码(空格)飞行里程。其中身份证号码由17位数字加最后一位校验码组成,校验码的取值范围为0~9和x共11个符号;飞行里程单位为公里,是(0, 15 000]区间内的整数。然后给出一个正整数M(≤105),随后给出M行查询人的身份证号码。对每个查询人,给出其当前的里程累积值。如果该人不是会员,则输出No Info。每个查询结果占一行。
2.3.1设计思路
/*用c++的map容器来做会很轻松*/
定义n存放人数,k存放最低里程,字符串id存放身份证号,length暂存单次里程
输入n、k
for i=0 to n
输入id、length
if 低于最小里程 then
length = k
end if
id键对应值加length的值
end for
输入n
for i=0 to n
输入id
if 存在id为键的键值对 then
输出
else
输出 No Info
end if
end for
2.3.2代码截图
2.3.3本题PTA提交列表说明。
- Q:因为先写的这一题,所以一开始还是犯得和题目2一样得错误,因为的这一题得时候刚会用map,所以不太熟练。
3、阅读代码
3.1 题目
3.2 解题思路
/*数据解释: primes[]:构造后续丑数的基数 res[]:存放由primes构造的丑数列表 *pos[]:存放指向res的指针数组*/
要求第n位丑数,函数返回存放了前n位丑数的数组
k为prims大小
res[0]=1 /*第一位丑数为1*/
初始化res全为1
next为丑数数组的下标
while next<n do
min1 取极大值
for i=0 to k /*找到下一个该存放的丑数*/
min1存放min1与pos[i]*prims[i]的较小值
end if
min1存入res数组
for i=0 to k
while pos[i]与prims[i]之积小于或等于res当前下标值 do
pos[i]++
end while
end for
next++
end while
3.3 代码截图
3.4 学习体会
代码在防止找到重复的丑数时对pos数组进行了更新,即当pos[i]与prims[i]的积小于等于当前偶数时,让pos[i]++的方式值得学习。代码中对数组的声明方式应该学习。