二叉树最长路径问题
发布时间
阅读量:
阅读量
【问题描述】
对给定的一个二叉树,请编写程序,完成功能:
输出从根结点到叶节点的最长路径长度,并输出第一条最长路径
【输入形式】
前序遍历二叉树
【输出形式】
两行,第一行为整型,长度;第二行为最长路径的各个节点。
【样例输入】
ABD##EHJ##KL##M#N###CF##G#I##
【样例输出】
7
ABEHKMN
【样例说明】
当多条最长路径出现时,请优先输出第一条;进行前序遍历操作时,请注意其中的#符号表示空节点。
思路
首先将问题分解为两个步骤:第一步是基于前序遍历构建一棵二叉树(create),第二步是计算该二叉树的最大深度(find_max_depth)。通常情况下,在仅提供前缀序列或结合中间序列时(比如前缀与中缀)才能唯一确定一棵二叉树。然而,在本题中所给带有空节点标记的信息足以完成这一构造过程。
伪代码
1.根据先序遍历建立二叉树create(基于栈)
(1)建立栈:
//根据先序遍历建立,存在回溯现象,想到栈(如果按照层次遍历是队列)
Node 包括左右指针,值data,还有访问次数visit_time
对于一个Node,每次访问到它,visit_time++,当第三次访问到它,也就是左右节点都满了,这个时候它出栈。
(2)根节点入栈
(3)for(int i=1;i<n;i++){//表示对输入的字符串逐个访问
栈顶元素visit_time++;
while(栈顶元素visit_time==3){
//注意这里不是if 因为后续存在连续上溯,连续pop过程
pop 栈顶元素
栈顶元素visit_time++;
//这句别忘,因为上一个栈顶元素出栈后,
//当前元素是下一个元素的儿子,所以对于下一个元素进行了访问。
}
if(pre[I]!='flag'){ //flag 为空节点标志,此处为"#",pre为给定的先序遍历字符串
if(栈顶元素visit_time = =1)成为栈顶元素左子树
else 成为栈顶元素左子树
}
当前元素入栈
}
代码解释
2、计算二叉树的最大深度find_max_depth。
该方法采用递归算法设计,并返回一个容器来存储路径中的节点信息;其本质与计算二叉树的高度相同;采用了包装函数结构,并利用递归机制实现该功能。
代码
#include <iostream>
#include<stack>
#include<vector>
using namespace std;
template<class Type>
class BinaryTree{
private:
struct Node{//二叉树的结点类
Node*left,*right;
Type data;
int visit_time;
Node():left(NULL),right(NULL){}
//参数化列表,内置结构体,结构体也可以有函数,不同之处:结构体定义中默认情况下的成员是public,而类定义中的默认情况下的成员是private的。
Node(Type item,Node *L=NULL,Node *R=NULL,int visit_time=0):data(item),left(L),right(R),visit_time(0){}
};
Node *root;//二叉树的根节点
public:
BinaryTree():root(NULL){}//其实里面的元素就只有一个根节点,内置类不用管他。
void clear(){
if(root!=NULL) clear(root);//防止到私有函数那里对于左子树和右子树的访问失败。
root=NULL;
}
~BinaryTree(){clear();} //有了new,要自己写析构函数,析构一般用clear;clear写在后面也可以哦
void Create(Type flag,string s){
stack<Node*> st;
root=new Node(s[0]);
st.push(root);
for (int i=1; i<s.length(); i++) {
st.top()->visit_time++;
while (st.top()->visit_time>=3) {
// cout<<"pop"<<st.top()->data<<endl;
st.pop();
st.top()->visit_time++;
// continue;
}
if (s[i]!=flag) {
Node* tmp=new Node(s[i]);
if (st.top()->visit_time==1) st.top()->left=tmp;
else st.top()->right=tmp;
st.push(tmp);
}
}
}
vector<Node*> find_max_depth(Node *t){
vector<Node*>lv;vector<Node*>rv;vector<Node*>v;
if(t==NULL)return v ;//注意:1.判空!!而且放在最前面,不然下一句会爆掉
else {
lv=find_max_depth(t->left);
rv=find_max_depth(t->right);
if(lv.size()>=rv.size()){
lv.insert(lv.begin(), t);
return lv;
}
else{
rv.insert(rv.begin(), t);
return rv;
}
}
}
void find_max_depth(){
vector<Node*> v =find_max_depth(root);
cout<<v.size()<<endl;
for(int i = 0; i != v.size(); i++){
cout<<v[i]->data;
}
}
private:
void clear(Node *t){ //递归妙哉!!
if(t->left!=NULL)clear(t->left);
if(t->right!=NULL)clear(t->right);
delete t;
}
};
int main() {
BinaryTree<char>tree;string s;
cin>>s;
tree.Create('#', s);
tree.find_max_depth();
return 0;
}
代码解释
全部评论 (0)
还没有任何评论哟~
