树的遍历
1、结点node定义
struct node{ int data; //数据域 vectorchild; //指针域,存放所有子结点的下标 int layer; }Node[maxn]; //结点数组,maxn为结点上限个数
2、新建一个结点
//新建一个结点 int index=0; int newNode(int v){ Node[index].data=v; Node[index].child.clear(); //清空子结点 return index++; }
3、树的先根遍历
void PreOrder(int root) { printf("%d ",Node[root].data); //访问当前结点 for(int i=0;i) { PreOrder(Node[root].child[i]); } }
4、树的层序遍历
void LayerOrder(int root) { queue<int> Q; Q.push(root); Node[root].layer=0; while(!Q.empty()) { int front=Q.front(); printf("%d ",Node[front].data); Q.pop(); for(int i=0;i) { int child=Node[front].child[i]; Node[child].layer=Node[front].layer+1; Q.push(child); } } }
5、练习题
PTA 1053 Path of Equal Weight (30 分)
https://pintia.cn/problem-sets/994805342720868352/problems/994805424153280512
#include#include #include #include #define maxn 105 using namespace std; int n,m; //结点数量,非叶子结点数量 int s; //给定要达到的权值数 int end_weight=0,end_num=0; int path[maxn]={0}; struct node{ int weight; //结点权重值 vector<int> child;//存放所有子结点下标 }Node[maxn]; bool cmp(int a,int b) { return Node[a].weight>Node[b].weight; } void DFS(int index,int numNode,int sum); //DFS 三个参数:①当前结点标号index ②当前path数组中结点个数 ③当前权值和sum int main() { int temp_id,temp_num,value; cin>>n>>m>>s; for(int i=0;i >Node[i].weight; for(int i=0;i ) { cin>>temp_id>>temp_num; for(int j=0;j ) { cin>>value; //temp_id结点的子结点id值 Node[temp_id].child.push_back(value); } sort(Node[temp_id].child.begin(),Node[temp_id].child.end(),cmp); } path[0]=0; //将根结点放入path数组中 DFS(0,1,Node[0].weight); //从根结点root开始,root的下标为0 return 0; } void DFS(int index,int numNode,int sum) { if(sum>s) return; //若当前权值和大于s,直接返回 if(sum==s) { if(Node[index].child.size()!=0) return; //若sum==s,但是当前结点不是叶子结点,也直接返回 for(int i=0;i ) { if(i==0) cout<<Node[path[i]].weight; else cout<<" "<<Node[path[i]].weight; } cout<<endl; return; } for(int i=0;i //枚举当前结点的所有孩子结点 { int child=Node[index].child[i]; path[numNode]=child; //将当前孩子结点加到path末尾 DFS(child,numNode+1,sum+Node[child].weight); } } /* 20 9 24 10 2 4 3 5 10 2 18 9 7 2 2 1 3 12 1 8 6 2 2 00 4 01 02 03 04 02 1 05 04 2 06 07 03 3 11 12 13 06 1 09 07 2 08 10 16 1 15 13 3 14 16 17 17 2 18 19 10 5 2 7 10 4 10 10 3 3 6 2 10 3 3 6 2 */
问题A:树查找
http://codeup.cn/problem.php?cid=100000612&pid=0
题目描述
有一棵树,输出某一深度的所有节点,有则输出这些节点,无则输出EMPTY。该树是完全二叉树。
输入
输入有多组数据。
每组输入一个n(1<=n<=1000),然后将树中的这n个节点依次输入,再输入一个d代表深度。
输出
输出该树中第d层得所有节点,节点间用空格隔开,最后一个节点后没有空格。
样例输入 http://codeup.cn/problem.php?cid=100000612&pid=1
题目描述
一棵树有n个节点,其中1号节点为根节点。
输入
第一行是整数n,表示节点数
后面若干行,每行两个整数a b,表示b是a的子节点。
输出
求这棵树的高度(根节点为第1层)
样例输入
5
1 2
1 3
3 4
3 5
样例输出
3
思路:这题主要在于记录每个结点所在的层号,最后遍历结点编号得到最大的那个层号即为树的层数;这里在构建结点类型时
添加layer变量来记录每个结点所在的层号,并借助树的层序遍历来
修改每个结点的层号,即从根结点开始,根结点的层号为1,其所有孩子结点的层号都是在根结点层号基础上加一,
如此下去直到队列为空,则遍历结束,输出最大的那个层号即为树的总层数;
#include#include #include #include #include using namespace std; #define maxn 105 int n,a,b; void heig(int root); //根结点下标 struct Node{ int layer; vector<int> child; }node[maxn]; int main() { int h=0; cin>>n; while(cin>>a>>b) { node[a].child.push_back(b); } heig(1); //根结点下标为1 for(int i=1;i<=n;i++) { if(node[i].layer>h) h=node[i].layer; } cout< endl; return 0; } //层次遍历树,并计算每个结点的深度 void heig(int root) { queue<int> que; que.push(root); node[root].layer=1; while(!que.empty()) { int frot=que.front(); que.pop(); for(int i=0;i ) { int id=node[frot].child[i]; node[id].layer=node[frot].layer+1; que.push(id); } } }