题目:输入一个整数和一棵二元树。从树的根结点开始往下访问一直到叶结点所经过的所有结点形成一条路径。打印出和与输入整数相等的所有路径。
例如输入整数22和如下二元树
10
/ \
5 12
/ \ / \
4 7 11 14
则打印出两条路径:10, 12和10, 5, 7。
思路:
1、当访问到某一节点(非空)时,该结点压入栈。
2、把该结点的值data与期望的值expect比较,若相等,打印出栈中的数据,即路径。
3、递归访问左子树,且更新期望值,期望值 = expect - data。
3、递归访问右子树,且更新期望值,期望值 = expect - data。
4、从栈中弹出结点值。
void pathSumOfK(BiTree T,int expectNum,vector<int>&path)
{
if (T)
{
path.push_back(T->data);
if(T->data==expectNum)
{
for(vector<int>::size_type ix = 0; ix < path.size()-1;ix++)
{
cout<<path[ix]<<",";
}
cout<<path[path.size()-1]<<endl;
}
pathSumOfK(T->lchild,expectNum-T->data,path);
pathSumOfK(T->rchild,expectNum-T->data,path);
path.pop_back();
}
}
// BiTree.h
#include <vector>
using namespace std;
typedef struct BiTNode{
int data;
struct BiTNode *lchild;
struct BiTNode *rchild;
}BiTNode, *BiTree;
BiTree CreateBiTree(); //先序,递归地建立树
void insert(BiTree& bitree,int data) void preOrder(BiTree T); //<span style="font-family:SimSun;">二叉查找树中插入节点</span>
void inOrder(BiTree T); // 中序遍历
void postOrder(BiTree T); //后序遍历
void levelOrder(BiTree T,int num); //按层次遍历
int nodeNum(BiTree T);
int leafnodeNum(BiTree T);
int depthOfTree(BiTree T);
void betwMinMax(BiTree T,char min,char max);
void pathSumOfK(BiTree T,int k,vector<int>& path);
#include "BiTree.h"
#include <iostream>
#include <vector>
using namespace std;
void insert(BiTree& bitree,int data)
{
if(!bitree)
{
bitree = (BiTree)malloc(sizeof(BiTNode));
bitree->data = data;
bitree->lchild = NULL;
bitree->rchild = NULL;
}
else
{
if(data<bitree->data)
{
insert(bitree->lchild,data); //并不需要判断bitree->child是否为空,为空时进入下层递归,由于参数为引用类型,下层递归中对空指针进行赋值时也即改变了上一层中对应的bitree->lchild,父节点和子节点的关系通过指针引用是保存下来了的。
}
else if(data>bitree->data)
{
insert(bitree->rchild,data);
}
else //已存在,插入失败,直接返回
{
return;
}
}
}
BiTree CreateBiTree() //先序,递归地建立树
{
BiTree T;
int x;
scanf("%c",&x);
if (x == '#') // -10为NULL
{
T = NULL;
}
else
{
T = (BiTree)malloc(sizeof(BiTNode)); //建根节点
T ->data = x;
T->lchild = CreateBiTree(); // 建左子树
T->rchild = CreateBiTree(); // 建右子树
}
return T;
}
void preOrder(BiTree T) //先序遍历
{
if (T==NULL)
{
return;
}
else
{
cout<<T->data<<" ";
preOrder(T->lchild);
preOrder(T->rchild);
}
}
void inOrder(BiTree T) // 中序遍历
{
if (T==NULL)
{
return;
}
else
{
inOrder(T->lchild);
cout<<T->data<<" ";
inOrder(T->rchild);
}
}
void postOrder(BiTree T) //后序遍历
{
if (T==NULL)
{
return;
}
else
{
postOrder(T->lchild);
postOrder(T->rchild);
cout<<T->data<<" ";
}
}
void levelOrder(BiTree T,int num) //按层次遍历
{
if (T)
{
BiTree *biqueue = (BiTree *)malloc(num*sizeof(BiTree));
int front = 0,rear = 0;
biqueue[rear++] = T;
while (front<rear)
{
BiTree curNode = biqueue[front];
cout<<curNode->data<<" ";
if (curNode->lchild)
{
biqueue[rear++] = curNode->lchild;
}
if (curNode->rchild)
{
biqueue[rear++] = curNode->rchild;
}
front++;
}
}
}
int nodeNum(BiTree T)
{
if (!T)
{
return 0;
}
else
{
int leftnum = nodeNum(T->lchild); //左子树上节点数
int rightnum = nodeNum(T->rchild); //右子树上节点数
return leftnum+rightnum+1;
}
}
int leafnodeNum(BiTree T)
{
if (!T)
{
return 0;
}
else if (T->lchild == NULL && T->rchild == NULL)
{
return 1;
}
else
{
int lnodenum = leafnodeNum(T->lchild); //左子树上节点数
int rnodenum = leafnodeNum(T->rchild); //右子树上节点数
return lnodenum+rnodenum;
}
}
int depthOfTree(BiTree T)
{
if (!T)
{
return 0;
}
else
{
int leftDepth = depthOfTree(T->lchild);
int rightDepth = depthOfTree(T->rchild);
return leftDepth>rightDepth ? leftDepth+1 : rightDepth+1;
}
}
void betwMinMax(BiTree T,char min,char max) // 找出二叉树中满足 min<x<max的x
{
if (T==NULL)
{
return;
}
else
{
if ((T->data>min)&&(T->data<max))
{
cout<<T->data<<" ";
}
betwMinMax(T->lchild,min,max);
betwMinMax(T->rchild,min,max);
}
}
//输入一个整数和一棵二元树。从树的根结点开始往下访问一直到叶结点所经过的所有结点形成一条根节点到叶子节点路径。打印出根节点到所有叶子节点的路径中与输入整数相等的所有路径
void pathSumOfK_rTol(BiTree T,int k,vector<int>&path)
{
if (T)
{
path.push_back(T->data);
if (T->lchild==NULL && T->rchild==NULL)
{
if(T->data==k)
{
for(vector<int>::size_type ix = 0; ix < path.size()-1;ix++)
{
cout<<path[ix]<<",";
}
cout<<path[path.size()-1]<<endl;
}
path.pop_back(); //该节点处理完,从容器中删除
}
else
{
pathSumOfK_rTol(T->lchild,k-T->data,path);
pathSumOfK_rTol(T->rchild,k-T->data,path);
path.pop_back();
}
}
}
//求出树中根节点到某一节点的路径和等于一给定整数的所有的路径。
void pathSumOfK(BiTree T,int expectNum,vector<int>&path)
{
if (T)
{
path.push_back(T->data);
if(T->data==expectNum)
{
for(vector<int>::size_type ix = 0; ix < path.size()-1;ix++)
{
cout<<path[ix]<<",";
}
cout<<path[path.size()-1]<<endl;
}
pathSumOfK(T->lchild,expectNum-T->data,path);
pathSumOfK(T->rchild,expectNum-T->data,path);
path.pop_back();
}
}
#include <iostream>
#include <time.h>
#include <stdlib.h>
#include <vector>
#include "BiTree.h"
using namespace std;
int main()
{
BiTree T = NULL ;
//srand((unsigned int)time(NULL));
/*
for (int i = 0; i<8;i++)
{
int x = rand()%20;
cout<<x<<" ";
insert(T,x);
}
*/
insert(T,10);
insert(T,5);
insert(T,12);
insert(T,4);
insert(T,7);
insert(T,6);
insert(T,0);
cout<<"\n";
inOrder(T);
cout<<"\n";
vector<int> path;
pathSumOfK(T,22,path);
pathSumOfK(T,28,path);
pathSumOfK(T,19,path);
cout<<"\n";
system("pause");
return 0;
}