输入一个整数和一棵二元树。从树的根结点开始往下访问一直到叶结点所经过的所有结点形成一条路径。打印出和与输入整数相等的所有路径。

题目:输入一个整数和一棵二元树。从树的根结点开始往下访问一直到叶结点所经过的所有结点形成一条路径。打印出和与输入整数相等的所有路径。

例如输入整数22和如下二元树

                                            10
                                           /   \
                                       5         12
                                    /   \        /    \
                                 4      7    11    14

则打印出两条路径:10, 1210, 5, 7

首先要引入一个概念,就是进程的概念,拿遍历树来说,虽然有多次的递归调用,但是始终是一个进程在执行,直到走到叶子节点为止,然后在退栈访问其他的节点。从给定的例子中可以看到,从根节点到叶子节点路径上加起来的值有的等于给定的值,有的小于,有的大于。所以当遍历到叶子节点的时候要与给定的值进行判断,如果相等,则打印出这条路径上的点。用vector或者栈都可以记录这些点。其实这种遍历就类似于进栈和出栈。

#include<iostream>
#include<vector>
using namespace std;
typedef struct tree_node {
	int data;
	struct tree_node *lchild, *rchild;
}tree_node, *bin_tree;
int tree_search(bin_tree T, tree_node *f, tree_node **p, int key) {
	if(!T) {
		*p = f;
		return false;
	}
	if(T->data == key) {
		*p = T;
		return true;
	} else if(key < T->data) {
		return tree_search(T->lchild, T, p, key);
	} else {
		return tree_search(T->rchild, T, p, key);
	}
}
int insert(bin_tree *T, int key) {
	tree_node *p;
	if(!tree_search(*T, NULL, &p, key)) {//如果树中不存在关键字
		tree_node *s = (tree_node*)malloc(sizeof(tree_node));
		s->data = key;
		s->lchild = s->rchild = NULL;
		if(!p)
			*T = s;
		else if(key < p->data)
			p->lchild = s;
		else
			p->rchild = s;
		return true;
	}
	return false;
}
void find_path(bin_tree T, int expected_sum, vector<int> &path, int ¤t_sum) {
	if(!T)
		return;
	current_sum += T->data;
	path.push_back(T->data);
	bool is_leaf = (!T->lchild) && (!T->rchild);
	if(is_leaf&& (current_sum == expected_sum)) {
		vector<int>::iterator it;
		for(it = path.begin(); it != path.end(); it++)
			cout << *it << " ";
		cout << endl;
	}
	if(T->lchild)
		find_path(T->lchild, expected_sum, path, current_sum);
	if(T->rchild)
		find_path(T->rchild, expected_sum, path, current_sum);
	current_sum -= T->data;
	path.pop_back();
}
static int tree_deep = 0;
void get_deep(bin_tree T, int ¤t_deep) {//获取树的高度
	if(!T)
		return;
	current_deep++;
	int is_leaf = (T->lchild == NULL) && (T->rchild == NULL);
	if(is_leaf) {
		if(current_deep > tree_deep)
			tree_deep = current_deep;
	}
	if(T->lchild)
		get_deep(T->lchild, current_deep);
	if(T->rchild)
		get_deep(T->rchild, current_deep);
	current_deep--;
}
int main() {
	bin_tree T = NULL;
	int current_deep = 0;
	if(insert(&T, 10)) {
		printf("ok\n");
	}
	if(insert(&T, 5)) {
		printf("ok\n");
	}
	if(insert(&T, 12)) {
		printf("ok\n");
	}
	if(insert(&T, 4)) {
		printf("ok\n");
	}
	if(insert(&T, 7)) {
		printf("ok\n");
	}
	get_deep(T, current_deep);
	cout << "tree_deep=" << tree_deep <<endl;
	vector<int> path;
	int current_sum = 0;
	int expected_sum = 22;
	find_path(T, expected_sum, path, current_sum);
	return 0;
}


  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值