Vulkan

Cracking The Coding Interview4.8

//You are given a binary tree in which each node contains a value. Design an algorithm to print all paths which sum up to that value. Note that it can be any path in the tree - it does not have to start at the root.
//
// 译文:
//
// 给定一棵二叉树,每个结点包含一个值。打印出所有满足以下条件的路径: 路径上结点的值加起来等于给定的一个值。注意:这些路径不必从根结点开始。




#include <iostream>
#include <string>
#include <vector>
#include <stack>


#include <stdlib.h>
using namespace std;


class tree
{
private:
	struct treenode
	{
		char data;
		treenode * left;
		treenode * right;
		treenode * parent;
	};


	treenode *root;


	int index;


	void create(treenode **p, char *str, int i, int size, treenode *fa)
	{


		if (i>size-1 || str[i] == '\0')
		{
			*p = NULL;
			return;
		}


		if (str[i] == '#')
		{
			*p=NULL;
		}
		else
		{
			*p = new treenode;
			(*p)->data = str[i];
			(*p)->parent = fa;
			create(&((*p)->left),str,2*i+1,size, *p);
			create(&((*p)->right),str,2*i+2,size, *p);
		}
	}





	void pOrder(treenode *p)
	{
		if (p==NULL)
		{
			return;
		}


	//	cout<<p->data<<"  "<<endl;
		pOrder(p->left);
		pOrder(p->right);
	}


	void zOrder(treenode *p)
	{
		if (p==NULL)
		{
			return;
		}
		zOrder(p->left);
		cout<<p->data<<"  "<<endl;
		zOrder(p->right);
	}


	void hOrder(treenode *p)
	{
		if (p==NULL)
		{
			return;
		}
		hOrder(p->left);
		cout<<p->data<<"  "<<endl;
		hOrder(p->right);
	}

	/***遍历每一个节点,朝上找父节点,如果能得到相等的sum ,则将该节点传递给print()***/
	void findpath(treenode *p, int sum)
	{
		//cout<<"findpath"<<endl;
		if (p == NULL)
		{
			return;
		}
		int i = 0;
		int temp = 0;
		treenode *pi = p;
		while(pi != NULL)
		{
			temp +=pi->data - '0';

			if (temp == sum)
			{
				print(p, i);
			}
			pi = pi->parent;
			i++;
		}
		findpath(p->left, sum);
		findpath(p->right, sum);
	}

	/***从节点朝父节点找,应反向打印***/
	void print(treenode *h, int level)
	{
		if (h == NULL)
		{
			return ;
		}
		//cout<<"print------"<<level<<endl;
		stack<int>s;
		int i=0;

		while(i <= level && h != NULL)
		{
			s.push(h->data - '0');
			h = h->parent;
			i++;
		}

		while(!s.empty())
		{	
			cout<<s.top()<<"  ";
			s.pop();
		}
		cout<<endl;
	}

	/***与上一方法类似,只是这里通过vector来记录每个节点上一层经过的路径***/
	void findpath(treenode *p, int sum, vector<int>&v, int level)
	{
		if (p == NULL)
		{
			return;
		}
		v.push_back(p->data - '0');
		int temp = 0;
		for (int i = level; i>-1;i--)
		{
			temp += v[i];/***从数组后面向前插入***/
			if (temp == sum)
			{
				print(v,i);
			}
		}
		vector<int>vl(v),vr(v);
		findpath(p->left,sum, vl, level+1);
		findpath(p->right,sum, vr, level+1);
	}
	/***从下向上,打印的是从该节点向上i层的data***/
	void print(vector<int>v, int i)
	{
		if (v.empty() || i<0)
		{
			return;
		}
		for (int j = i;j < v.size(); j++)
		{
			cout<<v[j]<<"  ";
		}
		cout<<endl;
	}


public:


	tree()
	{
		//root = create();
		root = NULL;
		index = 0;
	}


	/***输入扩展层次遍历序列,#表示该节点为空***/
	tree(char *s)
	{
		root = NULL;
		index = 0;
		if (s == NULL)
		{
			return;
		}


		int size = strlen(s);
		create(&root,s,0,size,NULL);
	}


	~tree()
	{
		/***清空二叉树***/
	}


	void printPathSum(int sum)
	{
		findpath(root, sum);
	}

	void printPathSum2(int sum)
	{
		vector<int>v;
		findpath(root, sum,v,0);
	}

	void preOrder(){pOrder(root);}
	void inOreder(){zOrder(root);}
	void postOreder(){  hOrder(root);}
};


int main()
{
	/***扩展层次序列简立树***/
	char t[14] = "1234#54#6##23";
	tree s(t);
	//s.preOrder();
	s.printPathSum(10);
	cout<<"xxxx"<<endl;
	s.printPathSum2(10);

	cout<<"Over"<<endl;
	return 0; 
}

posted on 2014-04-17 22:27  Vulkan  阅读(135)  评论(0编辑  收藏  举报

导航