DS二叉树—二叉树结点的最大距离(数据结构C语言版)

目录

题目描述:

输入

输出

 输入样例:

输出样例:

思路:

代码:

前言:

总结:


题目描述:

二叉树两个结点的距离是一个结点经过双亲结点,祖先结点等中间结点到达另一个结点经过的分支数。二叉树结点的最大距离是所有结点间距离的最大值。例如,下图所示二叉树结点最大距离是3,C和D的距离。

二叉树用先序遍历顺序创建,#表示空树。计算二叉树结点最大距离和最大距离的两个结点(假设二叉树中取最大距离的两个结点唯一)。

输入

测试次数T

第2行之后的T行,每行为一棵二叉树先序遍历结果(#表示空树)

输出

对每棵二叉树,输出树的结点最大距离和最大距离的结点,输出格式见样例。

 输入样例:

3
A##
ABC##EF#G###D##
ABEH###F#K###

输出样例:

0:
5:G D
4:H K

思路:

题目求的是任意2个结点间的距离的最大值,很容易能想到距离最远的2个结点必然是叶子结点,即最深的结点,而所求的这2个结点存在两种情况:路径经过根结点与不经过根结点。而无论是哪一种情况,所求2个结点都在以某一结点为根结点的树上,而这2个结点的距离则是这个树的左右子树深度(或高度)和。

所以问题就等同于:计算每个结点的左右子树的深度和,并保存左右子树最深层的值,最后取深度和的最大值及与之对应的左右最深层的值

代码:

#include <iostream>
#include <string>
using namespace std;

class BiTreeNode {
public:
	char  data;					//数据域
	BiTreeNode* leftChild, * rightChild;	//左右子树指针
	BiTreeNode() :leftChild(NULL), rightChild(NULL) {}
	~BiTreeNode() {}
};

class BiTree {
private:
	BiTreeNode* root;	//根结点指针
	string sTree;		//建树字符串
	int pos;			//标识建树字符串的当前字符位置
	int maxdis;			//最大距离
	int deep;			//保存子树深度
	int leftdeep, rightdeep;//保存左右子树深度
	char c;				//最深层的字符
	char leftc,leftc_temp, rightc,rightc_temp; //左右子树最深层字符

	BiTreeNode* CreateTree();//建树私有函数
	void getdeep(BiTreeNode* t,int i);//私有函数,求以t为根节点的子树的深度,i用来保存当前结点深度
	void getleftdeep(BiTreeNode* t);//求左深度
	void getrightdeep(BiTreeNode* t);//求右深度
	void getmax(BiTreeNode* t);		//私有函数,求最大距离的递归函数
public:
	BiTree() :root(NULL) { }
	void Create(string vArray);	//建树公有接口,参数是特定的先序遍历字符串
	void getmaxdis();//求最大距离并输出
};
//函数的实现
void BiTree::Create(string vArray)
{
	pos = 0;
	sTree.assign(vArray);	//把参数保存到内部字符串
	root = CreateTree();	//建树成功后root指向根结点
}
BiTreeNode* BiTree::CreateTree()//建树私有函数,先序遍历,递归建树
{
	BiTreeNode* t = NULL;
	if (sTree[pos] != '#')
	{
		t = new BiTreeNode();
		t->data = sTree[pos];
		pos++;
		t->leftChild = CreateTree();
		t->rightChild = CreateTree();
	}
	else
		pos++;
	return t;
}
void BiTree::getmaxdis()//求最大距离并输出
{
	maxdis = 0;
	getmax(root);
	cout << maxdis << ':';
	if (maxdis)
		cout << leftc <<' '<< rightc;
	cout << endl;
}
void BiTree::getmax(BiTreeNode* t)//计算以t结点为根结点的树的左右深度之和
{
	if (t != NULL)
	{
		deep = 0;
		getleftdeep(t);		//计算左子树的深度
		deep = 0;
		getrightdeep(t);	//计算右子树的深度
		if (maxdis < leftdeep + rightdeep)//如果目前保存的距离最大值小于这次求得的新树最大值,对其修改
		{
			maxdis = leftdeep + rightdeep;
			leftc = leftc_temp;
			rightc = rightc_temp;
		}//maxdis为最终所求最大距离,leftc和rightc为最终最大距离对应的2个结点,leftc_temp和rightc_trmp为当前新树(小树)的最大距离对应的结点
		//遍历出每个结点作根结点所对应的树
		getmax(t->leftChild);
		getmax(t->rightChild);
	}
}
void BiTree::getdeep(BiTreeNode* t,int i)//私有函数,求以t为根节点的子树的深度,i用来保存当前结点深度
{
	if (t != NULL)
	{
		i++;
		if (t->leftChild == NULL && t->rightChild == NULL)
		{
			if (deep < i)
			{
				deep = i;
				c = t->data;//最深层的字符
			}
		}
		getdeep(t->leftChild, i);
		getdeep(t->rightChild, i);
	}
}
void BiTree::getleftdeep(BiTreeNode* t)//求左深度
{
	if (t->leftChild == NULL)//左子树空则左子树深度为0
	{
		leftdeep = 0;
		leftc_temp = t->data;
		return;
	}
	t = t->leftChild;
	getdeep(t, 0);//求左子树深度
	leftdeep = deep;
	leftc_temp = c;
}
void BiTree::getrightdeep(BiTreeNode* t)//求右深度
{
	if (t->rightChild == NULL)//右子树空则右深度为0
	{
		rightdeep = 0;
		rightc_temp = t->data;
		return;
	}
	t = t->rightChild;
	getdeep(t, 0);//求右子树深度
	rightdeep = deep;
	rightc_temp = c;
}

int main()
{
	int t;
	string vArray;
	cin >> t;
	while (t--)
	{
		cin >> vArray;
		BiTree myTree;
		myTree.Create(vArray);
		myTree. getmaxdis();
	}
	return 0;
}

前言:

这篇文章算是我的学习笔记,是我在学《数据结构(C语言版)》遇到的值得记录的题目,记录下来方便我随时翻看以复习反思。

总结:

刚遇到这题的时候可把我难住了,当时用递归从底层开始求出最大距离但又保存不了对应的结点值,现在用的是直接从上往下求深度并保存对应的值。代码可以试试求深度函数返回一个值(深度或者对应的字符),应该能改善一些代码?

有无大佬有更简单的方法啊,捞捞~

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小柚也想长高

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值