二叉树经典面试题6~二叉树中和为某一值的路径

来源:互联网 发布:linux 2017年重大漏洞 编辑:程序博客网 时间:2024/05/16 05:09

 剑指offer面试题25~二叉树中和为某一值的路径

 一.问题描述

    输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。从树的根结点开始开始往下一直到叶子结点所经过的结点形成一条路径。

 二.问题分析

    这道面试题比较不常见的是二叉树的路径问题,所谓的二叉树路径是从根结点到叶子结点,换句话说二叉树的路径总是以根结点作为开始结点,在树的常见的四种遍历方式中只有前序遍历是从根结点开始的。在选定了遍历方式之后下面让我们来具体分析查找路径的栗子吧!!!

    

详细分析如下图:

  上树的前序遍历序列为:10 5 4 7 12

  1).访问根结点10,判断是否是叶子结点,不是当前路径结点值的和cur=10,辅助的数据结构path中只有一个结点10

  2).访问根结点的左孩子5,判断是否是叶子结点,不是当前路径值的和cur=15,path中存在两个结点:10,5

  3).访问结点5的左孩子4,判断是否是叶子结点,是当前路径值的和cur=19 != 22,不满足题意,path中存在三个节点:10,5,4。

  4).退回到节点值为4的上一层,但在返回之前要将辅助结构path中的结点4删除,并且cur减去删除结点的key.,cur=15,path中存在两个结点:10,5.按照前序遍历的顺序此时应该遍历的是结点值为5的右孩子结点7,

  5).访问结点7,判断是否是叶子结点,是当前路径值的和为22,path中存在三个节点:10,5,7,是一条合法的路径输出

  6).按照步骤4).的分析和前序遍历的要求,此时应该将path中的结点7,5删除,cur=10,遍历结点12

  7).访问结点12,判断是否是叶子节点,是当前路径结点值的和cur=22,path中有两个结点:10,12,满足题意将该路径打印出来

 三.代码实践

  如上述分析可得,所谓的辅助结构path是一种类似栈这种先进后出的数据结构,但是在找到路径之后我们是需要将所有结点的值都打印出来的,而栈一次只能pop掉一个元素,所以在实现的过程中用到了动态的数组-vector这种结构

  

template<class T>struct BinaryTreeNode{T _data;BinaryTreeNode<T> *_left;BinaryTreeNode<T> *_right;BinaryTreeNode(const T& data):_data(data),_left(NULL),_right(NULL){}};template<class T>class BinaryTree{typedef BinaryTreeNode<T> Node;public:BinaryTree():_root(NULL){}BinaryTree(const T* a,size_t size,const T& invalid){size_t index=0;_root=_CreatTree(a,size,index,invalid);}void FindPath(int num){assert(num >= 0);vector<Node *>path;int cur=0;_FindPath(_root,num,path,cur);}protected:void _FindPath(Node *root,int num,vector<Node *>& path,int& cur){cur += root->_data;path.push_back(root);//是叶子结点而且路径上的值和输入的值相等if(root->_left == NULL && root->_right == NULL && cur == num){cout<<"Legal Path:";vector<Node *>::iterator it=path.begin();while (it != path.end()){cout<<(*it)->_data<<" ";++it;}cout<<endl;}//不是叶子结点则继续遍历左子树和右子树if(root->_left)_FindPath(root->_left,num,path,cur);if (root->_right)_FindPath(root->_right,num,path,cur);//如果不是则返回上层结点并修改cur的值cur -= root->_data;path.pop_back();}Node *_CreatTree(const T* a,size_t size,size_t& index,const T& invalid){Node *root=NULL;assert(a);if(index < size && a[index] != invalid){root=new Node(a[index]);root->_left=_CreatTree(a,size,++index,invalid);root->_right=_CreatTree(a,size,++index,invalid);}return root;}protected:Node *_root;};void testFindPath(){int array[]={10,5,4,'#','#',7,'#','#',12};size_t size=sizeof(array)/sizeof(array[0]);BinaryTree<int> bt(array,size,'#');int index=0;cout<<"请输入需要查找路径的整数:";cin>>index;bt.FindPath(index);}

  总结:

      在查找路径的这道面试题中考察到了二叉树的遍历方式的选取,同时也考察了对辅助数据结构类似栈stack,队列queue,动态的数组vector,list的熟练掌握和正确的选取,总之是很有收获的啦~~~~

0 0
原创粉丝点击