DS博客作业05--树
1.本周学习总结
1.1.思维导图
1.2谈谈你对树结构的认识及学习体会
树的学习很难,但也很有意义,学好树,能让我们的代码简洁许多。在学习过程中,多在草稿纸上画图,这样能够帮助理解。对递归计算的理解很重要,但也是最花时间的部分。
2.pta实验作业
2.1题目1:输出二叉树每层节点
2.1.1设计思路
main函数{
定义字符串str;
定义树指针b;
定义 i=0,高度h;
输入str;
b=CreatBtree(str,i);
h=GetHeight(b);
PrintLevel(b,h);
return 0;
}
CreatBtree函数题目已给出;
GetHeight函数略过;
CreatBtree函数
{
定义 i=0,flag=0,k=0;
定义树指针 p;
定义队列指针 q;
if b 为空
输出"NULL";
return;
树的根结点入队b;
输出 “++i:根结点的data,”;
输出 “++i:”;
h=h-2;
if(根结点的左孩子不为空)
将其左孩子入队;
输出左孩子;
k++;
if(根结点的右孩子不为空)
将其右孩子入队;
输出右孩子;
k++;
出队;
while(队不为空)
flag=k;
k=0;
if h不等于0 输出 “++i:”;
while(flag不等于0)
p=队头的结点;
if(根结点的左孩子不为空)
将其左孩子入队;
输出左孩子;
k++;
if(根结点的右孩子不为空)
将其右孩子入队;
输出右孩子;
k++;
出队;
flag--;
if h不等于0 输出换行符;
h--
}
2.1.2代码截图
2.1.3PTA提交列表说明
- Q1:刚开始做的时候在如何输出正确格式的答案上花了很多时间。
- A1:添加上了一个计算树的高度的函数就问题解决了。
- Q2:创建树出了问题。
- A2:在函数CreatBtree中的形参i前应加上引用符号&。
2.2题目2:根据后序和中序遍历输出先序遍历
2.2.1设计思路
main函数{
定义树根结点 b=NULL
定义数组post[30],in[30];
定义结点数N,i;
b=new BTNode;
输入N;
for i=0 to i<N
输入post[i];
for i=0 to i<N
输入in[i];
b=CreatBT(post,in,N);
输出"Preorder:";
GetPre(b);
return 0;
}
CreatBT函数{
定义树结点指针 b;
定义整型数 r,k,*p;
if N小等于0 return NULL
r=*(post+N-1);
b=new BTNode;
b->data=r;
for p=in to p<in+N
如果 *p 等于 r break;
k=p-in;
b的左孩子等于CreatBT(post,in,k);
b的右孩子等于CreatBT(post+k,p+1,N-k-1);
return b;
}
GetPre函数{
if b不为空
输出“ ”以及b->data;
GetPre(b的左孩子);
GetPre(b的右孩子);
}
2.2.2代码截图
2.2.3PTA提交列表说明
- Q1:测试点一和四发生段错误
- A1:发现是树结点的类型定义错误。
2.3题目3:还原二叉树
2.3.1设计思路
main函数{
定义树结点指针 b;
定义字符数组pre[50],in[50];
定义结点数N;
b=new BTNode;
输入N;
输入pre,in;
b=CreatBT(pre,in,N);
输出GetHeight(b);
return 0;
}
CreatBT函数{
定义树结点指针 b;
定义字符指针 *p;
定义整型数 k;
if N小等于0 return NULL;
b=new BTNode;
b->data=*pre;
for p=in to p<in+N
如果 *p 等于 *pre break;
k=p-in;
b的左孩子等于CreatBT(post+1,in,k);
b的右孩子等于CreatBT(post+k+1,p+1,N-k-1);
return b;
}
GetHeight函数{
定义整型数 lh,rh;
if 结点BT为空 return 0;
else
lh等于GetHeight(BT->lchild);
rh等于GetHeight(BT->rchild);
若lh大于rh,返回lh+1;反之,返回rh+1;
}
2.3.2代码截图
2.3.3PTA提交列表说明
- 答案正确
3.阅读代码
3.1题目:玩转二叉树
给定一棵二叉树的中序遍历和前序遍历,请你先将树做个镜面反转,再输出反转后的层序遍历的序列。所谓镜面反转,是指将所有非叶结点的左右孩子对换。这里假设键值都是互不相等的正整数。
输入第一行给出一个正整数N(≤30),是二叉树中结点的个数。第二行给出其中序遍历序列。第三行给出其前序遍历序列。数字间以空格分隔。
3.2解题思路
build函数 //la,ra表示中序遍历 lb,rb表示前序遍历
{
if la大于ra
return 0;
定义整形数 x等于pre[lb];
定义整形数 p1等于la,p2;
while(in[p1]不等于x) //在前序遍历中找到根节点
p1++;
p2等于p1-la;
a[x]的左孩子等于build(la,p1-1,lb+1,lb+p2);
a[x]的右孩子等于build(p1+1,ra,lb+p2+1,rb);
return x;
}
bfs函数
{
定义队列 q;
将先序遍历的根结点入队
定义整型数组 b[55];
定义整型数 k=0;
while(队列不为空) //利用队列来按层输出
{
定义 z等于队头;
出队;
b[k++]等于z;
if a[z]的右孩子不为空
将a[z]的右孩子入队;
if a[z]的左孩子不为空
将a[z]的左孩子入队;
}
for i=0 to k-1
if i等于0 输出“b[i]”;
else 输出“ b[i]”;
return;
}
main()函数
{
定义 n;
输入n;
for i=0 to n-1
输入in[i];
for i=0 to n-1
输入pre[i];
bfs(pre[0]);
return 0;
}
3.3代码截图
3.4学习体会
- 学习到可以使用万能头文件#include<bits/stdc++.h>
- 平时更经常使用二叉链的储存结构进行操作,但本题使用顺序存储结构会更加精简。
- 层次遍历输出的函数值得借鉴。