《算法笔记》9.3 树的遍历

一.树的静态写法
1.结构体:

struct node {
	typename data;
	1.int child[maxn]; //指针域,maxn 为结点上限个数 
	2.vector child; //防止开辟的空间过大
}Node[maxn];

2.新建结点:

int index = 0;
int newNode(int v) {
	Node[index].data = v;
	Node[index].child.clear();
	return index++;
}

3.如果题目中不涉及结点的数据域,上面的结构体可以简化地写成 vector 数组:vector<int> child[maxn];

二.树的先根遍历

void preOrder(int root) {
	printf("%d ", Node[root].data);
	for(int i = 0; i < Node[root].child.size(); i++) 
		preOrder(Node[root].child[i]);
}

三.树的层序遍历

void layerOrder(int root) {
	queue<int> q;
	q.push(root);
	while(!q.empty()) {
		int front = q.front();
		printf("%d", Node[front].data);
		q.pop();
		for(int i = 0; i < Node[front].child.size(); i++)
			q.push(Node[front].child[i]);
	}
}

四.题目
1.PAT A1053
思路:
1).存储要输出的数,用一个数组就够了,每次循环时同下标的数组元素都不同,所以可以用来储存不同答案;
2).DFS的函数参数:当前数组下标,path数组当前的大小,当前的权值和;
3).路径从大到小:用 sort 函数给子结点排序(权值从大到小);

代码:

#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn = 110;
int N, M, S;
int path[maxn];
struct node {
	int data;
	int num;
	vector<int> child;
}Node[maxn];

bool cmp(int a, int b) {
	return Node[a].data > Node[b].data;
}

void search(int index, int numNode, int sum) {
	path[numNode] = Node[index].data;
	sum += Node[index].data;
	numNode++;
	if(Node[index].num == 0) {
		if(sum == S) {
			for(int i = 0; i < numNode; i++) {
				printf("%d", path[i]);
				if(i == numNode - 1) printf("\n");
				else printf(" ");
			}
		}
		return;
	}
	if(sum > S) return;
	for(int i = 0; i < Node[index].num; i++) {
		search(Node[index].child[i], numNode, sum);
	}	
}
int main() {
	scanf("%d%d%d", &N, &M, &S);
	for(int i = 0; i < N; i++) scanf("%d", &Node[i].data);
	for(int i = 0; i < N; i++) Node[i].num = 0;
	int x, numChild, y;
	for(int i = 0; i < M; i++) {
		scanf("%d%d", &x, &numChild);
		Node[x].num = numChild;
		for(int j = 0; j < numChild; j++) {
			scanf("%d", &y);
			Node[x].child.push_back(y);
		}
		sort(Node[x].child.begin(), Node[x].child.end(), cmp);
	}
	search(0, 0, 0);
	return 0;
}

2.PAT A1079
注意:
1).在此题的 DFS 函数中,不能将 ans 作为参数,若为参数,每一层的 ans 都是一样的(最后会是0), i = 0 时 ans 的变化到不了 i = 1 里;
在这里插入图片描述

代码:

#include<cstdio>
#include<vector>
#include<cmath>
using namespace std;
const int maxn = 100010;
int N;
double P, r;
double ans = 0;
struct node {
	int id;
	int weigh;
	vector<int> child;
}Node[maxn];

void DFS(int index, int level) {
	if(Node[index].weigh != 0) {
		ans += P * Node[index].weigh * pow(1 + r / 100, level);
		return;
	}
	for(int i = 0; i < Node[index].child.size(); i++) {
		DFS(Node[index].child[i], level + 1);
	}
}

int main() {
	scanf("%d%lf%lf", &N, &P, &r);
	int k, child, w;
	for(int i = 0; i < N; i++) {
		scanf("%d", &k);
		Node[i].id = i;
		Node[i].weigh = 0;
		if(k == 0) {
			scanf("%d", &w);
			Node[i].weigh = w;
		}
		else {
			for(int j = 0; j < k; j++) {
				scanf("%d", &child);
				Node[i].child.push_back(child);
			}
		}
	}
	DFS(0, 0);
	printf("%.1lf\n", ans);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值