一 问题描述:
输入一个整数和一棵二元树。从树的根结点开始往下访问一直到叶结点所经过的所有结点形成一条路径。打印出和与输入整数相等的所有路径。
如图,输入整数70 和如下二叉排序树
输出为:30 15 25
二 解题思路:
利用二叉树的前序遍历,
注意:路径是从根到叶子的所有节点的序列
三: 代码
/*
This is a free Program, You can modify or redistribute it under the terms of GNU
*Description:在二叉排序树中查找和为某一值的所有路径
*Language: C++
*Development Environment: VC6.0
*Author: Wangzhicheng
*E-mail: 2363702560@qq.com
*Date: 2012/11/24
*/
#include <iostream>
#include <cstdlib>
#include <vector>
#include <stack>
#include <algorithm>
#include <ctime>
using namespace std;
/*----------------- 二叉排序树-----------------------------------------------------------*/
template<class Type> //向前引用
class BST;
/*
*二叉排序树结点类
*@data:结点的数据域
*@left:结点的左孩子指针
*@right:结点的右孩子指针
*/
template<class Type>
class BSTNode {
private:
Type data;
BSTNode *left;
BSTNode *right;
public:
friend class BST<Type>;
BSTNode() {
}
BSTNode(Type data,BSTNode *left=0,BSTNode *right=0) {
this->data=data;
this->left=left;
this->right=right;
}
BSTNode(const BSTNode &node) {
this->data=node.data;
this->left=node.left;
this->right=node.right;
}
BSTNode & operator=(const BSTNode &node) {
this->data=node.data;
this->left=node.left;
this->right=node.right;
return *this;
}
void setData(Type& data) {
this->data=data;
}
Type getData() const {
return this->data;
}
void setLeft(BSTNode *left) {
this->left=left;
}
BSTNode * getLeft() const {
return this->left;
}
void setRight(BSTNode *right) {
this->right=right;
}
BSTNode * getRight() const {
return this->right;
}
};
/*
*二叉排序树类
*@root:二叉排序树根指针
*@v:要建立二叉排序树所需数据的向量
*/
template<class Type>
class BST {
private:
BSTNode<Type> *root; //二叉排序树的根指针
vector<Type>v; //存放数据域的向量
stack<Type>Stack; //辅助栈,用来存放路径
/*
*向二叉排序树插入一个新的数据
*@root:根指针
*@data:一个新的数据
*/
void Insert(BSTNode<Type> *&root,const Type &data) {
if(!root) {
root=new BSTNode<Type>(data,0,0);
}
else if(root->getData()>=data) {
Insert(root->left,data);
}
else {
Insert(root->right,data);
}
}
/*
*中序遍历二叉排序树
*@p:初始值是指向二叉排序树的根结点
*/
void VisitBST_In_order(BSTNode<Type> *p) {
if(!p) return;
VisitBST_In_order(p->getLeft());
cout<<p->getData()<<" ";
VisitBST_In_order(p->getRight());
}
/*
*按照逆向中序遍历寻找 即右孩子->根->左孩子
*/
void SearchTopN(BSTNode<Type> *p) {
static int n;
if(!p) return;
else {
if(n<N) SearchTopN(p->getRight());
if(++n<=N) TopN.push_back(p->getData());
if(n<N) SearchTopN(p->getLeft());
}
}
/*
*检查栈中所有元素的和是不是等于num
*如果是,函数返回true
*/
bool CheckStack(Type num) {
stack<Type>temp; //辅助栈
Type s=0; //用来求和
while(Stack.empty()==false) {
s+=Stack.top();
temp.push(Stack.top());
Stack.pop();
}
while(temp.empty()==false) {
Stack.push(temp.top());
temp.pop();
}
if(s==num) return true;
else return false;
}
/*
*打印栈中数据
*/
void PrintStack() {
static int k;
stack<Type>temp; //辅助栈
while(Stack.empty()==false) {
temp.push(Stack.top());
Stack.pop();
}
cout<<"第"<<++k<<"条路径是:"<<endl;
while(temp.empty()==false) {
cout<<temp.top()<<" ";
Stack.push(temp.top());
temp.pop();
}
cout<<endl;
}
void PrintPathEqualToAInteger(BSTNode<Type> *p,Type num) {
if(p) {
Stack.push(p->getData());
PrintPathEqualToAInteger(p->left,num);
PrintPathEqualToAInteger(p->right,num);
/*
*如果符合条件,则打印出路径
*!p->getLeft() && !p->getRight()可以保证栈顶元素是叶子节点的元素
*此时保存在栈里的是一条从根节点到达叶子节点的路径
*/
if(!p->getLeft() && !p->getRight() &&CheckStack(num)==true) PrintStack();
if(Stack.empty()==false) Stack.pop();
}
}
public:
/*
*二叉排序树的构造函数
*@input:输入的向量,保存着等待建立二叉排序树的数据
*此函数将向量input的内容保存到向量v中,并且对v进行混洗,一定程度上避免产生单支树
*/
BST(vector<Type>&input) {
v.clear();
vector<Type>::iterator it;
for(it=input.begin();it!=input.end();it++) {
v.push_back(*it);
}
//random_shuffle(v.begin(),v.end()); //将向量混洗,避免产生单支二叉排序树
root=0;
}
/*
*创建二叉排序树
*/
void Create() {
vector<Type>::iterator it;
for(it=v.begin();it!=v.end();it++) {
Insert(root,*it);
}
}
void show() {
VisitBST_In_order(root);
cout<<endl;
}
void PrintPathEqualToAInteger(const Type &num) {
PrintPathEqualToAInteger(root,num);
}
};
void main() {
srand(unsigned(time(0)));
int N=6;
int input[]={30,15,5,25,40,35};
vector<int>v(input,input+N);
BST<int>bst(v);
bst.Create();
bst.show();
int num;
cout<<"请输一个整数:";
cin>>num;
if(!cin.good()) {
cerr<<"输入数据格式错误,程序退出!"<<endl;
exit(1);
}
bst.PrintPathEqualToAInteger(num);
}
四 测试