1.学习总结
1.1树结构思维导图
1.2 树结构学习体会
- 由于树的这部分代码使用了大量的递归,导致许多思路变得很抽象,有些难以理解,对很多细节和内容掌握的并不深刻,很多代码也都是看着课本写的。树虽然有些难度,但是树结构可以提高算法的效率,节约时间,这部分的作用还是很大的。
2.PTA实验作业
题目1:6-3 先序输出叶结点
1.设计思路
遍历树
若BT->Left==NULL&&BT->Right==NULL,则为叶子节点输出
然后再递归判断BT的左孩子节点和右孩子节点是否为叶子节点
2.代码截图
3.PTA提交列表说明
- 无问题。
题目2:6-4 jmu-ds-表达式树
1.设计思路
计算二叉树
若T->data为数字字符,则返回对应的数值
若T->data为运算符ch,则利用递归返回EvaluateExTree( T->lchild ) ch EvaluateExTree( T->rchild )的值。
特别注意的是ch==/时,需要对分母EvaluateExTree( T->rchild )进行判断,若为0时,则提示错误。
构建表达式树
建立两个栈,一个存放运算符,一个存放树节点
遍历for i=0 to str[i]==0
若str[i]为数字字符,则创建一个data为str[i],左右孩子都NULL的节点t,并将t推进树栈。
若str[i]为运算字符
则将str[i]对应的运算符与运算符栈栈顶的运算符,比较优先级。
若栈顶的运算符优先级高,则两次取出树栈的栈顶,创建节点CreateExpTree( t , e2 , e1 , Op.top() ),再将t存入树栈,再把运算符的栈顶出栈,直到运算符栈顶与str[i]优先级相等。
end for
while(op.size())
把运算符栈中的剩余运算符一个一个出栈,并且分别创建节点。
end
将T指向创建的表达式树。
2.代码截图
3.PTA提交列表说明
- 本题借鉴了他人代码,并且理解了思路。
在计算二叉树中,分母为0时,我用return 0,导致答案错误.
解决方法:改为exit(0)。
题目3:7-8 jmu-ds-二叉树叶子结点带权路径长度和
1.设计思路
利用递归创建二叉树
因为第i个节点的左孩子为2i,右孩子为2i+1
所以利用这个关系将顺序二叉树转为链式二叉树,bt->lchild =CreateBTree(str,2*i), bt->rchild =CreateBTree(str,2*i+1)。
递归出口为 if(i>len-1 || i<=0) return NULL,if(str[i]==\'#\') return NULL。
递归求WPL
先设置一个全局变量wpl
若BT==NULL,则返回空
若BT为叶子节点,则累加wpl += (BT->data-\'0\') * floor
BT指向孩子节点时,floor就加1
所以递归Wpl(BT->lchild,floor+1),Wpl(BT->rchild,floor+1);
2.代码截图
3.PTA提交列表说明
- 一开始忘将节点的数值字符转化为对应的数值,导致计算错误。
解决方法:BT->data-\'0\'
3.截图本周题目集的PTA最后排名
3.1 PTA排名
3.2 我的得分:2.5
4. 阅读代码
寻找两个节点的最低公共祖先
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(!p || !q) return NULL;
vector<TreeNode*> path1,path2;
findPath(root,p,path1);
findPath(root,q,path2);
if(path1.empty() || path2.empty()) return NULL;
int i = 0;
while(i<path1.size() && i<path2.size() && path1[i]==path2[i]) i++;
return path1[i-1];
}
bool findPath(TreeNode *root, TreeNode *p, vector<TreeNode*> &path){
if(!root) return false;
if(root==p) {
path.push_back(p);
return true;
}
path.push_back(root);
bool flag1 = findPath(root->left,p,path);
if(flag1) return true;
bool flag2 = findPath(root->right,p,path);
if(flag2) return true;
path.pop_back();
return false;
}
- 如果是二叉搜索树,就简单了,如果当前节点均小于(大于)这两个节点,那么他们的最低公共祖先一定在当前节点的右子树(左子树)中,然后递归找,直到遇到某个节点,使得这两个节点不在同一侧,那么那个节点就是他们的最低公共祖先。但如果不是二叉搜索树,我们可以遍历树,找到这两个节点,并记录从根节点到它们的路径,然后在这两条路径上找它们的第一个非公共节点。