参考文章:
http://xingyunbaijunwei.blog.163.com/blog/static/7653806720122284428687/
输入一个整数和一棵二元树。从树的根结点开始往下访问一直到叶结点所经过的所有结点形成一条路径。
打印出和与输入整数相等的所有路径。
例如输入整数22 和如下二元树
10
/ \
5 12
/ \
4 7
则打印出两条路径:10, 12 和10, 5, 7。
思路:
1、当访问到某一节点时,把该结点的值添加到当前和变量,且把该结点压入栈中。
2、若结点为叶子结点,且当前和变量==期望的和,则打印栈中的结点值,即为所需的路径。
3、若结点不是叶子结点,继续访问它的左孩子结点,访问它的右孩子结点。
4、删除该结点。包括从当前和变量中减去结点值,从栈中弹出结点值。此时,已回到父结点。
#include <stdio.h>
#include <stdlib.h>
static count=0;
typedef struct node
{
int key;
struct node *pleft;
struct node *pright;
}Node;
int CreateTreeByInsertData(Node **p,int k)//理解为什么用二级指针
{
if(*p==NULL)
{
*p=(Node *)malloc(sizeof(Node));
(*p)->key=k;
(*p)->pleft=(*p)->pright=NULL;
return 1;
}
else if(k == (*p)->key)
return 0;
else if(k < (*p)->key)
return CreateTreeByInsertData(&(*p)->pleft,k);
else
return CreateTreeByInsertData(&(*p)->pright,k);
}
void InOrderTravel(Node *p)//中序遍历树
{
if(p == NULL)
return ;
InOrderTravel(p->pleft);
printf("%d ",p->key);
InOrderTravel(p->pright);
}
void ClearTree(Node** tree)//删除树的操作,
{
if(*tree==NULL)return;
ClearTree(&(*tree)->pleft);
ClearTree(&(*tree)->pright);
free(*tree);
*tree=NULL;
}
void printPath(int path[],int top)
{
int i;
count++;
printf("这是第%d组:",count);
for(i=0;i<top;i++)
printf("%d ",path[i]);
printf("\n");
}
void findPath(Node *root, int sum,int top,int path[])//回溯遍历的核心
{
path[top++] = root->key;
sum -= root->key;
if (root->pleft == NULL && root->pright==NULL)
{
if (sum == 0)
{
printPath(path, top);
}
}
else
{
if (root->pleft != NULL)
findPath(root->pleft, sum, top,path);
if (root->pright!=NULL)
findPath(root->pright, sum, top,path);
}
top --;
sum += root->key;
}
int main()
{
int i;
Node *proot = NULL;
/*Node *ListHead = NULL;
Node *ListTail = NULL;*/
int data[] = {10,5,12,4,7};
int path[20]={0};
//依次插入一些数据,创建一个二叉排序树
for(i=0; i<sizeof(data)/sizeof(int); i++)
//CreateTreeByInsertData(proot, data[i]);
CreateTreeByInsertData(&proot, data[i]);
InOrderTravel(proot);
findPath(proot,22,0,path);
ClearTree(&proot);
return 0;
}