JLU-数据结构荣誉课-第三次实验-解题报告
一、二叉树最长路径
题目
给定一棵二叉树T,求T中的最长路径的长度,并输出此路径上各结点的值。若有多条最长路径,输出最右侧的那条。
输入格式:
第1行,1个整数n,表示二叉树有n个结点, 1≤n≤100000.
第2行,2n+1个整数,用空格分隔,表示T的扩展先根序列, -1表示空指针,结点用编号1到n表示。
输出格式:
第1行,1个整数length,length表示T中的最长路径的长度。
第2行,length+1个整数,用空格分隔,表示最右侧的最长路径。
输入样例:
- 5
- 1 2 -1 -1 3 4 -1 -1 5 -1 -1
输出样例:
- 2
- 1 3 5
题意:
求一颗二叉树的最长路径,并输出该条路径。
思路
- [造树]
递归构造。读入一个数据,如果该数据为结束标志(本题-1),则置当前结点为NULL,退出函数;若该数据为正常数据,则创建一个新结点,接着递归构造左右子树。
参考代码如下:
void BuildTree(TreeNum *&t)
{
int tmp;
cin>>tmp;
if(tmp==-1)
{
t=NULL;
return ;
}
else
{
t=new TreeNum;
t->data=tmp;
BuildTree(t->Left);
BuildTree(t->Right);
}
}
- [求最长路径]
依旧递归求解。检测当前结点,如果当前结点为空,则返回0;如果当前结点不为空,则返回左右子树中长度较长的值+1。
参考代码如下:
int MaxLength(TreeNum *t)
{
if(!t)
return 0;
else
{
int Left=MaxLength(t->Left)+1;
int Right=MaxLength(t->Right)+1;
return Left>Right?Left:Right;
}
}
- [打印最长路径]
如果依然递归求解,会造成超时,内存超限。因此考虑在之前的函数中,保存路径。这里我想到的方法是:在树结点中加入一个新的变量(int Oper),用来保存当前结点最长路径的方向,即保存当前结点的左右子树中,较长的那个子树的方向(0代表左,1代表右)。
[求最长路径]修改后的代码如下:
int MaxLength(TreeNum *t)
{
if(!t)
return 0;
else
{
int Left=MaxLength(t->Left)+1;
int Right=MaxLength(t->Right)+1;
if(Left>Right)//由于要求打印尽可能右面的最长路径,因此只有Left>Right的时候,最长路径方向才是左
{
t->Oper=0;
return Left;
}
else
{
t->Oper=1;
return Right;
}
}
}
参考代码
#include "iostream"
#include "stack"
using namespace std;
struct TreeNum
{
int data;//数据
int Oper;//最长路径的方向
TreeNum *Left;//左儿子
TreeNum *Right;//右儿子
};
void BuildTree(TreeNum *&t);//这里从略
int MaxLength(TreeNum *t);//这里从略
int main()