1.学习总结
1.1查找的思维导图
1.2 查找学习体会
本章的查找更像是对之前学习的线性结构,树形结构等的应用,全新的知识不多,所以相对来说比较轻松一点点。虽然新知识不多,但是涉及到的内容更广更全面了,同时也暴露了前面知识的缺漏,比如对树的掌握对递归的掌握还不扎实。而且查找这章除了要求的代码外更多的是关于平衡树的调整操作,B树的删除增加调整操作等,还有关于各种查找方式对应的查找效率ASL的计算是不同的,要搞清楚这些计算首先得先清楚这些查找的原理然后再记忆其ASL的计算方式才不容易混淆。关于STL目前只了解了其中的map的一点点小小的用法,并知道它不同于hashmap,同时了解到实现map的红黑树,但是只知道红黑树是一种有颜色的AVL树,关于它的很多原理和操作还是一头雾水,只知道红黑树可不是一般厉害呐...
2.PTA实验作业
2.1 题目1:6-3 二叉搜索树中的最近公共祖先
2.2 设计思路
int find(Tree T, int x ) //查找x是否在二叉搜索树T中
{
if(T结点为空) return 0;
if(T结点值等于x)return 1;
if(T结点值小于x)返回递归调用find(T->Right,x)的结果
if(T结点值大于x)返回递归调用find(T->Left,x)的结果
}
int LCA( Tree T, int u, int v ) //寻找u v的最近公共祖先
{
if(T为空树) return ERROR;
if(u或v不在树T中) return ERROR;
if(u或v有一个在根上) return u或v的值;
if(u,v一个在左子树上,一个在右子树上) return 最近介于u,v之间大小的结点T的值;
if(u和v都在左子树上) return LCA( T->Left, u, v );
if(u和v都在右子树上) return LCA( T->Right, u, v );
}
2.3 代码截图
2.4 PTA提交列表说明
-
Q1:部分正确呐
-
A1:差一个sample等价的样例没有过...因为没有建树的代码所以没法在DevC运行也不知道sample有错就提交了,在思考很久以后发现题目并未规定u,v的大小,而我默认u比v小,但其实u也可能比v大,所以把注释内容补上就全对啦~
-
Q2:漫长的寻找思路过程
-
A2:一开始确实没有啥清晰思路的..就想着说递归调用下去,然后有找到这个数就return true回去,然后最近的祖先一定是最先T->left和T->right同时都为true的结点...但是一开始并不知道可以自己再写一个函数就放弃这个想法(其实现在想想一开始这个想法也是ok的只要情况再多分几种就好啦~)然后在大神提示下发现公共祖先的大小介于两者之间然后就没有然后了..判断大小介于两者之间好办,但是怎么判断是他们的祖先呢,于是想到了后序遍历,利用后序遍历的根总是在后面的特点去分析了样例一,后序遍历结果为:2 1 4 5 3 7 8 6 ,7的祖先只有8 或者 6 ,再加上介于27之间的条件,发现只有6是满足要求的,所以这个办法还是有一定可行度的,但是再举几个比较大一些的树以后发现并不受用...且发现也有可能都在同一边的情况..试用范围太小了只能忍痛放弃这个想法...不过在上面各种失败经历后总算是把情况想得相对全面一些啦也算是he了...哦对了大神还提供一个想法是说可以考虑把子树往上缩减,比如说找到2,就把子树旋转下,即2到1的位置,2就上移一位离祖先近了,继续旋转下去最终最近的祖先的左右支是2和7...好吧我觉得他的想法也很不错呐
但是我不fei写这个操作的代码溜...
2.1 题目2:7-1 QQ帐户的申请与登陆
2.2 设计思路
1.申请string,string类型的map并命名为information,定义字符order为输入操作,定义字符数组num[10]存放qq账号,字符数组password[16]存放用户qq密码
2.输入n
3.for i=1 to i=n
分别输入order的值,number和password的值
if(操作为登录)
在map中查找是否有账号为number的值
若有找到:判断是否这个账号在map中一一对应的密码与用户输入的密码是否相同,相同:输出Login: OK 不同:输出ERROR: Wrong PW
若没找到:输出ERROR: Not Exist
if(操作为申请账号)
在map中查找是否有账号为number的值
若有找到:则输出ERROR: Exist
若没找到:在map中放入账号和密码一一对应的关系,并输出New: OK
end for
2.3 代码截图
2.4 PTA提交列表说明。
-
Q1:前几个输出都不对,明明是L(登录)竟然显示new ok...
-
A1:输出order的值并判断进入了登录和申请账号中的哪个分支
发现order的值竟然是换行符,而且进入了N(申请)分支中,回过头来看代码发现order在scanf语句中对应的%c可以读入上一条输入n的值后的换行符,这也正是问题所在!于是多加了一条getchar()语句吃掉上一条语句末尾的换行符,然后就正确输出啦~
- Q2:兴高采烈去提及代码啦但是
(废话没有但是怎么会在写调试过程呢) - A2:看到测试点0说的sample答案错误我还觉得挺奇怪的,毕竟我运行结果是对才有勇气提交的呀...然后看到测试点2说的上下界,然后第一反应就是数组的大小是不是设小了...发现确实是数组设小啦,别忘记 字符数组的末尾要放 的喂!改正后就迷之全对啦~(所以其实还是不清楚第0个测试点错哪儿了哭唧唧)
- Q3:发现除了这种做法以外还有一种申请两个map的做法
- A3:申请两个map,一个用来正常放账号密码一一对应关系,还有一个用来放账号和该账号是否存在一一对应关系,这种做法就节省了我的这种做法的遍历查找是否存在的时间,但是空间上它要多申请一个map的内存大小,所以说时间和空间有得必有失呐~
2.1 题目3:7-2 航空公司VIP客户查询
2.2 设计思路
1.申请string,int类型的map并命名为information,定义整数型变量n来存放查询或输入的顾客数量,k为最低里程,flight为顾客的飞程公里,定义字符数组identity[20]存放顾客身份证号码
2.输入要更新信息的顾客数量n,k
3.for i=1 to i=n
分别输入identity和flight的值
若flight小于最低里程,将flight改成k
在map中查找是否有身份证为identity的顾客
若没找到:将该顾客的identity和flight一一对应关系放入map中
若有找到:将该顾客的flight更新为原先的flight加上本次的flight
end for
4.输入要查询信息的顾客数量n
5.for i=1 to i=n
输入要查询顾客的identity
在map中查找是否有身份证为identity的顾客
若没找到:输出No Info
若有找到:输出该identity对应的flight
end for
2.3 代码截图
2.4 PTA提交列表说明。
- Q1:部分正确
- A1:
第三位乘客的结果不对,仔细回过头来看题目才发现
补上注释的语句就对啦~但是这么幼稚的错误实在是不应该出现的...
3.截图本周题目集的PTA最后排名
3.1 PTA排名
3.2 我的总分:2.5
4. 阅读代码
/*红黑树查找结点*/
//----------------------------------------------------
//rb_search_auxiliary:查找
//rb_node_t* rb_search:返回找到的结点
//----------------------------------------------------
static rb_node_t* rb_search_auxiliary(key_t key, rb_node_t* root, rb_node_t** save)
{
rb_node_t *node = root, *parent = NULL;
int ret;
while (node)
{
parent = node;
ret = node->key - key;
if (0 < ret)
{
node = node->left;
}
else if (0 > ret)
{
node = node->right;
}
else
{
return node;
}
}
if (save)
{
*save = parent;
}
return NULL;
}
//返回上述rb_search_auxiliary查找结果
rb_node_t* rb_search(key_t key, rb_node_t* root)
{
return rb_search_auxiliary(key, root, NULL);
}
- 网上关于红黑树的介绍并不是很多,找了很久才看到一篇比较适合红黑树的初学者学习的博客cr:https://www.cnblogs.com/v-July-v/archive/2011/01/03/1983699.html 码着用来学习红黑树~