第一步,创建二叉树,这在上一篇文章”二叉树的创建和遍历“中详细讲解。
第二步, 如何查找? 思想如下: 利用栈的思想,一个一个将树的结点压入栈,同时利用一个全局变量来记录栈中所有树结点数据之和,判断是否等于所要查找之和?同时判断当前树结点是否为叶子结点?如果同时满足,则找到一条路径,打印栈中数据。(逆序输出)
先创建如下二叉树:
先序创建二叉树,输入0则返回上一级,详见上一篇文章。
则输入:1213000210003200500
如果查找和为6的路径:
理论上可推出有: 1,2,2,1 和1,3,2
代码:
// Bitree.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
using namespace std;
typedef int type;
int record=0;
//定义数结点
typedef struct bNode
{
type data;
struct bNode *lchild;
struct bNode *rchild;
}bNode,*bTree;
//定义路径结点 栈结点
typedef struct path
{
bNode *tree;
struct path *next;
}path,*pPath;
//初始化路径
void InitPath(pPath &L)
{
L=(pPath)malloc(sizeof(path)); //相当于栈顶指针
if(NULL==L)
{
cout<<"申请内存失败!"<<endl;
exit(-1);
}
L->next=NULL;
}
//树节点入栈
void Push(pPath L, bTree T)
{
pPath temp=(pPath)malloc(sizeof(path));
if(NULL==temp)
{
cout<<"申请内存失败!"<<endl;
exit(-1);
}
temp->tree=T;
temp->next=L->next;
L->next=temp;
}
//树节点出栈函数
void Pop(pPath L)
{
pPath temp=L->next;
if(NULL==temp)
{
cout<<"栈为空!"<<endl;
exit(-1);
}
L->next=temp->next;
}
//判断是否为叶子结点
int IsLeaf(bTree T)
{
return (NULL==T->lchild)&&(NULL==T->rchild);
}
//计算栈长度
int len(pPath L)
{
pPath temp=L->next;
int i=0;
while(NULL!=temp) //找到
{
i++;
temp=temp->next;
}
return i;
}
//打印栈中所有数据
void Print(pPath L)
{
int length=len(L);
type *a= new type[length];
pPath temp=L->next;
int i=0;
while(NULL!=temp)
{
a[i++]=temp->tree->data;
temp=temp->next;
}
for(int j=length-1;j>=0;j--)
cout<<a[j]<<" ";
cout<<endl;
delete []a;
}
//查找符合条件的路径
void find_path(pPath L,bTree T, int sum)
{
Push(L,T);
record+=T->data;
if((sum==record)&&(IsLeaf(T)))
{
Print(L);
}
if(NULL!=T->lchild) //递归查找左孩子结点
{
find_path(L,T->lchild,sum);
}
if(NULL!=T->rchild) //递归查找右孩子结点
{
find_path(L,T->rchild,sum);
}
record-=T->data;
Pop(L);
}
//先序创建二叉树
void CreateBitree(bTree &T)
{
type ch;
cin>>ch;
if(0==ch)
{
T=NULL;
}
else
{
T=(bTree)malloc(sizeof(bNode));
if(NULL==T)
{
cout<<"申请内存失败!"<<endl;
return ;
}
T->data=ch;
CreateBitree(T->lchild);
CreateBitree(T->rchild);
}
}
//先序遍历
void PreOrder(bTree T)
{
if(T)
{
cout<<T->data<<" ";
PreOrder(T->lchild);
PreOrder(T->rchild);
}
}
//中序遍历
void InOrder(bTree T)
{
if(T)
{
InOrder(T->lchild);
cout<<T->data<<" ";
InOrder(T->rchild);
}
}
//后序遍历
void PostOrder(bTree T)
{
if(T)
{
PostOrder(T->lchild);
PostOrder(T->rchild);
cout<<T->data<<" ";
}
}
//计算树的深度
int TreeDepth(bTree T)
{
if(!T) return 0;
int n1=TreeDepth(T->lchild);
int n2=TreeDepth(T->rchild);
return (n1>n2?n1:n2)+1;
}
int _tmain(int argc, _TCHAR* argv[])
{
bTree T;
pPath L=NULL;
int sum=0;
InitPath(L);
CreateBitree(T);
PreOrder(T);
cout<<endl;
InOrder(T);
cout<<endl;
PostOrder(T);
cout<<endl<<"树的深度为:"<<TreeDepth(T)<<endl;
cout<<"输入查找的和:";
cin>>sum;
cout<<endl;
cout<<"和为"<<sum<<"的结点序列:"<<endl;
find_path(L,T,6);
return 0;
}
运行结果: