您的位置:首页 > 健康 > 养生 > 网页制作要学什么课程_建筑工程网络计划技术_子域名网址查询_优化大师tv版

网页制作要学什么课程_建筑工程网络计划技术_子域名网址查询_优化大师tv版

2025/4/17 9:38:23 来源:https://blog.csdn.net/2401_85828611/article/details/145512994  浏览:    关键词:网页制作要学什么课程_建筑工程网络计划技术_子域名网址查询_优化大师tv版
网页制作要学什么课程_建筑工程网络计划技术_子域名网址查询_优化大师tv版

目录

1.P1305 新二叉树

题目

分析

代码

提交结果

2.P4913 【深基16.例3】二叉树深度 

题目

分析

代码

提交结果

3.★[NOIP 2001 普及组] 求先序排列 

题目

分析

统一做法

算法

示意图

递归函数的模版

代码

提交结果

4. P1827 [USACO3.4] 美国血统 American Heritage

题目

分析

代码

提交结果


1.P1305 新二叉树

题目

新二叉树 - 洛谷

分析

把字母当成对应的ASCII码编号的节点处理,例如a节点,'a'的ASCII码为97,其编号为97号,向往常一样使用前序遍历

代码

#include <iostream>
using namespace std;
const int N = 1000;
char _left[N], _right[N], root, node;
int n;
void preorder(char root)
{if (root == '*')return;cout << root;preorder(_left[root]);preorder(_right[root]);
}int main()
{cin >> n;cin >> root; cin>>_left[root] >> _right[root];//读根节点和其左右子树 n--;while (n--){cin >> node;cin >> _left[node] >> _right[node];}preorder(root);return 0;
}

注:不建议写成cin >> root >>_left[root] >> _right[root];和cin >> node >> _left[node] >> _right[node];在Dev C++和VS上测试都有问题,分开读

提交结果

2.P4913 【深基16.例3】二叉树深度 

题目

【深基16.例3】二叉树深度 - 洛谷

分析

二叉树的深度求解方法参见109.【C语言】数据结构之求二叉树的高度文章

公式:二叉树的高度 == 1 + max(左子树的高度, 右子树的高度)

代码

#include <iostream>
#include <algorithm>//max函数 
using namespace std;
const int N=1e6+10;
int _left[N],_right[N],n;
int i=1;//根节点编号为1
int treeheight(int root)
{if (root==0)//停止递归的条件 return 0;//root!=0int _left_height=treeheight(_left[root]);//左子树高度 int _right_height=treeheight(_right[root]);//右子树高度 return max(_left_height,_right_height)+1;//返回左右子树高度较大的那个,且根节点高度为1也要加上 
}int main()
{cin>>n;while(n--){cin>>_left[i]>>_right[i];i++;}cout<<treeheight(1);return 0;
}

提交结果

3.★[NOIP 2001 普及组] 求先序排列 

题目

[NOIP 2001 普及组] 求先序排列 - 洛谷

分析

本题和下面这些题是同类题型,且做法固定

给出一棵二叉树的先序中序排列。求出它的后序排列(本文第4题)

注:给出一棵二叉树的先序与后序排列无法还原二叉树,必须知道中序排列!!!

统一做法

★重复此步骤:先确定根节点,再按根节点划分左右子树

以测试用例BADC BDCA为例分析

先确定根节点:

因为中序排列为BADC,后序排列为BDCA,那么根节点一定为A(后序排列最后访问的一定是根!!),打印A

再按根节点划分左右子树:

因为中序排列按左子树->根-->右子树遍历,所以划分为B | A | DC,显然 B为左子树部分(打印B),DC为右子树部分,则后序排列为B | DC | A

处理左子树B:

先确定根节点:B,再按根节点划分左右子树:为空,不用划分

处理右子树DC:先确定根节点:由于中序排列和后序排列都是同一个顺序DC,那么C为根节点(后序排列最后访问的一定是根!!),打印C,再按根节点划分左右子树:D | C | ,则D为C的左子树,打印D,C的右子树不存在.

则打印的前序排列为ABCD

算法

先确定根节点:利用循环来找,设在中序排列找到的下标为pos(可以调用find函数或者写循环来手动查找)

再按根节点划分左右子树:中序排列划分:[left1,pos-1],pos,[pos+1,right1],左区间长度为pos-1-left1+1==pos-left,右区间长度为right1-pos-1+1==right1-pos,则可以推出后序排列的划分[left2,left2+(pos-left1)-1],[left2+(pos-left1),right2-1],right2

再分别对左子树递归: [left1,pos-1]和[left2,left2+(pos-left1)-1],传四个参数

右子树递归:[pos+1,right1]和[left2+(pos-left1),right2-1],传四个参数

示意图

?处下标的算法:绿色部分长度相同,因此(pos-1)-(left1)==(?)-left2

注:left1,right1,left2,right2不一定就在边界处,这里仅示意

递归函数的模版

void print_preorder(int left1,int right1,int left2,int right2)
{//先写递归结束条件if (......) return; //再确定根节点cout<<......;int pos=......;//最后按根节点划分左右子树,对左右子树递归//中序排列划分:[left1,pos-1],pos,[pos+1,right1]//后序排列的划分:[left2,left2+(pos-left1)-1],[left2+(pos-left1),right2-1],right2//左子树:[left1,pos-1]和[left2,left2+(pos-left1)-1]//右子树:[pos+1,right1]和[left2+(pos-left1),right2-1]//递归处理左子树print_preorder(?,?,?,?);//递归处理右子树print_preorder(?,?,?,?);
}

代码

利用递归算法

#include <iostream>
#include <string>
using namespace std;
string inorder_str,postorder_str;void print_preorder(int left1,int right1,int left2,int right2)
{//递归结束条件if (right1<left1||right2<left2) return; //先确定根节点cout<<postorder_str[right2];int pos=inorder_str.find(postorder_str[right2]);//再按根节点划分左右子树//中序排列划分:[left1,pos-1],pos,[pos+1,right1]成立前提:left1<=pos-1<=right1 //后序排列的划分:[left2,left2+(pos-left1)-1],[left2+(pos-left1),right2-1],right2成立前提:left2<=left2+(pos-left1)-1<right2-1//递归处理左子树print_preorder(left1,pos-1,left2,left2+(pos-left1)-1);//递归处理右子树print_preorder(pos+1,right1,left2+(pos-left1),right2-1);
}int main()
{cin>>inorder_str>>postorder_str;print_preorder(0,inorder_str.size()-1,0,postorder_str.size()-1);return 0;
}

注意前序遍历的顺序: (打印)根-->(递归)左-->(递归)右

提交结果

4. P1827 [USACO3.4] 美国血统 American Heritage

题目

[USACO3.4] 美国血统 American Heritage - 洛谷

分析

给中序遍历和前序遍历,打印后序遍历,和第3题思路相同,不再赘述

代码

#include <iostream>
#include <string>
using namespace std;
string inorder_str,preorder_str;void print_postorder(int left1,int right1,int left2,int right2)
{//结束条件if (left1>right1||left2>right2) return;//找根,划分左右子树 int pos=inorder_str.find(preorder_str[left2]);//递归左子树 print_postorder(left1,pos-1,left2+1,right2+pos-right1);//递归右子树print_postorder(pos+1,right1,right2+pos-right1+1,right2);//打印根节点 cout<<preorder_str[left2];
}int main()
{cin>>inorder_str>>preorder_str;print_postorder(0,inorder_str.size()-1,0,preorder_str.size()-1);return 0;
}

注意后序遍历的顺序:(递归)左-->(递归)右-->(打印)根

提交结果

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com