树的遍历
1、结点node定义
struct node{ int data; //数据域 vector<int> child; //指针域,存放所有子结点的下标 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<Node[root].child.size();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<Node[front].child.size();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 <cstdio> #include <vector> #include <iostream> #include <algorithm> #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<n;i++) cin>>Node[i].weight; for(int i=0;i<m;i++) { cin>>temp_id>>temp_num; for(int j=0;j<temp_num;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<numNode;i++) { if(i==0) cout<<Node[path[i]].weight; else cout<<" "<<Node[path[i]].weight; } cout<<endl; return; } for(int i=0;i<Node[index].child.size();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层得所有节点,节点间用空格隔开,最后一个节点后没有空格。
样例输出
EMPTY
2 3
思路:根据完全二叉树的性质,首先依据给定n计算二叉树的深度(高度)为log2(n+1) 向上取整或log2n向下取整再加1。再依据给定的深度进行判断,
若大于树的最大深度,则直接输出EMPTY,
否则依据第h层树的结点数为[2h-1,min(2h-1,n)]来输出第h层结点元素值;
x#include <iostream> #include <algorithm> using namespace std; int height(int n); int main() { int n,m,h,hei,value; //n为结点数,m为深度 while(cin>>n) { if(n==0) break; h=height(n); for(int i=0;i<n;i++) cin>>value; cin>>hei; if(hei>h) cout<<"EMPTY\n"; else{ int last=(n>=(pow(2,hei)-1))?pow(2,hei)-1:n; for(int j=pow(2,hei-1);j<=last;j++){ if(j!=last) cout<<j<<" "; else cout<<j<<endl; } } } return 0; } int height(int n) { int value=1; int h=0; while(value<=n) { value*=2; h++; } return h; }
问题B:树的高度
一棵树有n个节点,其中1号节点为根节点。
输入
第一行是整数n,表示节点数
后面若干行,每行两个整数a b,表示b是a的子节点。
输出
求这棵树的高度(根节点为第1层)
3
思路:这题主要在于记录每个结点所在的层号,最后遍历结点编号得到最大的那个层号即为树的层数;这里在构建结点类型时
添加layer变量来记录每个结点所在的层号,并借助树的层序遍历来
修改每个结点的层号,即从根结点开始,根结点的层号为1,其所有孩子结点的层号都是在根结点层号基础上加一,
如此下去直到队列为空,则遍历结束,输出最大的那个层号即为树的总层数;
#include <cstdio> #include <iostream> #include <cmath> #include <vector> #include <queue> 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<<h<<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<node[frot].child.size();i++) { int id=node[frot].child[i]; node[id].layer=node[frot].layer+1; que.push(id); } } }
天晴了,起飞吧