DS博客作业05--树
1.本周学习总结
学习体会:
树是一种重要的结构在生活上有大量的使用,例如文档和目录都是如此。起初在接触树的时候完全不知道这样一种结构是怎么实现的,
对这样一种结构的实现感到神奇。在对二叉树的学习中渐渐对树有了认识,它的结构体有左右两个孩子指针,这样可以很好的保存下一层
的数据。在有了认识后最重要的是用代码去实现这个功能,然后看到了树的遍历基本都是递归就有点懵了。递归对我来说一直都使用的不
顺,经过在pta反复的使用后也算是比较熟悉了,在加上在大作业中对孩子兄弟树的操作后,感觉树还掌握的不错。
2.PTA实验作业
2.1.题目1:6-4 jmu-ds-表达式树
2.1.1设计思路
```c void类型 InitExpTree函数传入BTree &T,string str 定义BTree变量p,p1,p2 定义BTree的栈s,op 定义int变量i while i小于str的长度 do if str[i] 是数 then 新建结点p存str[i],并将p入栈s else str[i]是符号 then if 栈op为空或str[i]的优先级大于op栈顶 then 新建结点p存str[i],并将p入栈op else then while 栈op不空且str[i]的优先级小于op栈顶 do s出栈2次分别由p2和p1保存 op出栈一次由p保存 p左孩子指向p1,p右孩子指向p2,将p入栈s if 栈op不空且str[i]的优先级等于于op栈顶 then op出栈 else continue i++ if 栈s为空 then T=NULL return while 栈op不空 do s出栈2次分别由p2和p1保存 op出栈一次由p保存 p左孩子指向p1,p右孩子指向p2,将p入栈s T=p doule类型 EvaluateExTree函数传入BTree T 定义double型变量x,y if T==NULL then return 0 switch 判断T->data 若为+号 return EvaluateExTree(T->lchild)+EvaluateExTree(T->rchild)break 若为-号 return EvaluateExTree(T->lchild)-EvaluateExTree(T->rchild)break 若为*号 return EvaluateExTree(T->lchild)*EvaluateExTree(T->rchild)break 若为/号 x=EvaluateExTree(T->lchild),y=EvaluateExTree(T->rchild) if y=0 then 输出“divide 0 error!” 退出程序 else return x/y break 若为数字 return T->data-'0'
```
2.1.2代码截图
2.1.3本题PTA提交列表说明。
Q1:刚开始看到这个题目完全没有思路,直接放弃了
A1:经过老师在上课的时候说要用到2个栈来存放,感觉可以开始尝试了
Q2:写了一半发现这题的代码量有点多
A2:翻上去发现有一些功能已经有了,崩溃
Q3:虽然上面有符号优先级比较的函数,但是一直看不懂
A3:经过了多次的尝试才明白了代码是怎么实现优先级的比较
Q4:完成代码后又出现了有括号的数据不行的情况
A4:查找发现代码位置有误,并修改了代码位置最终解决
2.2.题目2:7-6 修理牧场
2.2.1设计思路
这里讲sort做法的思路
```c main函数 定义int型vector变量s 定义int变量n,a,x,y,i,sum=0 输入数量n for i=0 to n-1 do 输入a,并存入s 用sort对s排序 while s长度不等于1 do x等于s中第一个数据,并将s中第一个数据删掉 y等于s中第一个数据,并将s中第一个数据删掉 sum=sum+x+y for i=0 to i等于s的长度减1 do if x+y<s[i] break 将x+y插入s中i的位置 输出sum return 0
```
2.2.2代码截图
哈夫曼树代码
sort排序做法
优先队列法
2.2.3本题PTA提交列表说明。
Q1:刚开始完全不会这一题
A1:百度看到这一题可以用优先队列,而且代码就几行,十分简便
Q2:但是毕竟那个没学过,所以又想换一个办法
A2:所以就有了哈夫曼树的代码,错误主要是min的初始化太小
Q3:看到哈夫曼的时间复杂度太大意识到不行
A3:所以又用sort写了一遍,综上还是优先队列的时间复杂度小,代码量少
2.3.题目3:7-7 朋友圈
2.3.1设计思路
```c main 定义并查集数组t 定义int数组sum 定义整型N,M 输入人数N和集合M 定义整型i,x,a=0,b=0 for i=1 to i=N do //数组初始化 t[i].rank=0,t[i].data=i,t[i].parent=i while M-- do //遍历集合 输入当前集合人数x 当x不为0 输入第一个人a for i=0 to i=x-2 do //遍历剩下的人 输入人b 调用UNION函数联合a和b 定义整型max=0 for i=1 to i=N do //遍历所有人 x=Find(i,t) //找头结点 sum[x]++ //记录头结点相同的人数,即朋友圈人数 if sum[x]>max do max=sum[x] //记录最大朋友圈 输出最大朋友圈人数max Find函数 if a==t[a].parent 返回a //说明是头结点 else return Find(t[a].parent,t) //不是就继续递归寻找 UNION函数 int x为a的头结点,y为b的头结点 if x==y then //选择rank大的为新的头结点 if t[x].rank>t[y].rank t[y].parent=x else t[x].parent=y; if t[x].rank == t[y].rank then t[y].rank++ //相等的时候合并后rank要加一 ```
2.3.2代码截图
2.3.3本题PTA提交列表说明。
这题主要问题就是并查集不熟悉,经过了看课本和查百度才在最后艰难的完成了这一题的代码。
3、阅读代码
3.1 题目
题目描述
输入一串二叉树,用遍历先序打出。
输入输出格式
输入格式:
第一行为二叉树的节点数n。
后面n行,每一个字母为节点,后两个字母分别为其左右儿子。
空节点用*表示
输出格式:
先序排列的二叉树
3.2 解题思路
n行数据,逐行输入,存入tree数组中
在DLR函数中进行先序的输出操作,需要
注意的是,左孩子和双亲之间是两倍的关系,
左孩子和右孩子差1.
3.3 代码截图
3.4 学习体会
1.代码打多了对陌生代码可以有较快的反应能力,可以快速明白题目的解题方法
2.本题多采用数组的方式,而我们多采用指针的方式,多了解数组方面也有好处