DS-博客作业07
1.本周学习总结(0--2分)
1.1思维导图
1.2 谈谈你对查找运算的认识及学习体会。
在查找这一章,我学习的比较认真,但是还是有部分没太清楚。这章没有前一章树那么多的代码要记,但是还是要用心。 比如老师介绍了几种容器:对于STL容器;c++中有两种类型的容器:顺序容器和关联容器。老师只介绍了map容器,map是key-value形式的,在写题目的时候,使用map会方便很多,容器类自动申请和释放内存,我们无需new和delete操作。对于迭代器来说,我看了百度很迷糊,map会根据key自动排序,这一点在很多功能的实现上大大的降低了代码量,可以很简单的实现想要的功能。
其次,这一章的学习,代码上面不是很长。而且查找中有些代码我们以前学过,折半啊,冒泡等,其余的一些查找方法代码上也不是很多,理解起来还是不难。
这一章的学习又涉及到了一些递归。在处理上还是有一些难度,但是直接背代码还是可以的。哈希查找这一块主要是ASL 的计算,这种问题把哈希表列出了基本上不会出错了,就是要注意ASL不成功的时候除以的是p。哈希链的方式也是雷同的,还是不会很难理解。总体上这一章的学习还是算比较顺利的,重点知识相对前几章是比较好理解。
最后,这一章的一个难点就是好像又牵扯到了递归,又回到了之前那段有点迷糊的感觉。递归总体上还是不是掌握的很好,只能背代码。
2.PTA实验作业(6分)
2.1.题目1:题目名称
2.1.1设计思路(伪代码)
Find 函数
{
if T为空 then return 0
end if
if x 等于 关键字 then
return 1
else if x 大于 关键字 then
调用函数find(T->Right, x)
else
调用函数find(T->Left, x)
end if
}
LCA函数
{
if T 为空 then 返回错误
end if
if find(T, u) 返回0或者find(T, v)返回0 then 返回错误
end if
if T->Key 大于等于u且T->Key小于v或 T->Key 小于等于 u且T->Key 大于等于 v then
返回 T->Key
if u > T->Key then
LCA(T->Right, u, v);
else if u < T->Key then
LCA(T->Left, u, v);
}
2.1.2代码截图
2.1.3本题PTA提交列表说明。
问题1:起初看到这道题,就感觉没思路,沉住气看了一会儿,思路如下:
有两种情况:1.u,v不在树中;
2.u,v在树中:u,v都在左子树上;
u,v都在右子树上;
u,v一个在左子树上,一个在右子树上;
u,v有一个在根上。
但是编出来的代码不对,测试数据有过不了,我就搜了一下百度。
答:发现把上面第一种情况漏了,没有思考全面。加上去后,可以通过。
2.2.题目2:题目名称
2.2.1设计思路(伪代码)
Main:
定义整数n,m;符串 a,b,c;
set<string> match; //初始化set容器match 存账号
map<string,string> iter; //存的密码
输入n;
while n>0且n-- do
输入 a、b、c;
if a等于字符L then
if match.find(b)等于match.end() then //已有账号中没找到该账号
输出ERROR: Not Exist
else
if iter[b]不等于c
输出ERROR: Wrong PW
else
输出Login: OK
end if
else if a等于N
if match.find(b)不等于match.end() then
输出ERROR: Exist
else
输出New: OK
iter[b]=c;
match.insert(b);
end if
end if
end while
2.2.2代码截图
2.2.3本题PTA提交列表说明。
问题1:首先定义了个数组用来存放QQ号和密码的,发现有个测试点事有界限的问题。
答:修改了数组的大小再交上去过了那个测试点。
问题2:在map中查找是可以用map[]查找,若map[]不存在,会直接插入,导致再次查找时结果为存在。
答:改用库函数在map中查找用map.find()查找。
2.3 题目3:题目名称
2.3.1设计思路(伪代码)
定义map<string,long int> vip
输VIP人数n和航程k
定义char ID[19];long int mile;
for i=0 to n
输入ID,mile
若mile小于k,让mile=k
vip[ID]+=k //ID 不存在时会直接插入,所以直接加
end for
for i=0 to n
输入 ID
若vip中有该ID,输出vip[ID]
若没有,输出 No Info
end for
2.3.2代码截图
2.3.3本题PTA提交列表说明。
问题1:第一思路就是用map将客户的id(string类型)与里程road(int类型)形成映射,然后直接用id查找添加里程或输出里程。
答:发现会超时。改了别的办法。
问题1:一开始用string定义会出现超时问题,编译器运行无反应,
答:改用数组来,结果就可以了。
问题2:用编译器后面两个测试点运行超时,不知道为啥。
答:要用scanf和printf,不能使用c++的语法,这里我也不知道为啥,把上面代码的输入和输出改成c语法就可以了。
3、阅读代码(-2--2分)
3.1 题目
介绍代码解决问题
3.2 解题思路
把序列1建立成一棵二叉搜索树,然后在树中按顺序遍历搜索序列2中的每一个数,如果每次搜索时,经过的结点都被搜索过,那就是一样的两棵搜索树;否则,如果某次搜索时,经过有前面没被搜索过的结点,那这两棵树就不一样。
例如序列1构造的树BT,序列2中的序列我们按顺序一个一个的在BT里搜索。一开始搜索5,5是根结点,找到了,接下来到4,查找4时会经过左结点3,这时的3时前面没被搜索过的,所以这样我们就可以判别这两个序列形成的二叉搜索树时不同的。根据这个方法,我们在构建二叉搜索树的结构时就要加一个标记,flag=0;用作后面判别时,判断这个结点有没有被搜索过,flag一开始定义为0,表示没搜索过,被搜索过后的结点的flag就令它等于1。
3.3 代码截图
3.4 学习体会
如果我拿到这个题目,一开始肯定不会这样想思路,应该是这样:
很自然的我们就想到是两棵树做遍历,比较每一个结点,也就是用递归,一开始看根结点同不同,然后递归比较左子树同不同,右子树同不同,这样的方法代码和遍历相似。代码类似这样
这个题目的思路给了我一种很新的感觉,虽然代码上面没这么有优势,不过里面的定义结构体的时候加了一个falg判断,这一点在很多时候可以借用。他使用了这个结构后,思路也是不一样 了,
函数的两个参数一个是树BT,根据一个序列建立的二叉搜索树。另一个参数X为要判别是否一致的另一个插入序列。断结点的flag,如果被搜索过,也就是flag1,就会做递归遍历搜索,否则如果遇到flag0,也就是遇到没被搜索过的结点,这时就要做判断了:判断这个没被搜索过的结点的Data和X是否相等,如果相等,就是说这个结点就是我要搜索的结点,就把它的Data设为1。如果该结点的Data和X不相等,也就是说在搜索过程中,没找到要搜索的元素时,就碰到了前面没被搜索过的结点,那么就可以判断这个插入序列和树BT是不相等的了。这个判别函数的结构就是一个查找的结构。