【10分】F. DS二叉树—二叉树结点的最大距离

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

二叉树用先序遍历顺序创建,#表示空树。计算二叉树结点最大距离和最大距离的两个结点(假设二叉树中取最大距离的两个结点唯一)。
【10分】F. DS二叉树—二叉树结点的最大距离_第1张图片

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

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

输入样例1

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

输出样例1

0:
5:G D
4:H K

思路

 通过先序遍历建树,pos标识建树字符串的当前字符位置,如果当前字符是"#"就pos++并返回空值。否则将该字符存入当前树节点的值中并pos++。
递归建立左子树和右子树。
  通过preOrder(BiTreeNode *T, int height)找到T节点的最大深度,height表示当前深度。当一个节点的左孩子和右孩子都是空值时,说明达到了叶子节点。此时,如果深度大于最大深度,更新最大深度,并将该叶子节点的值存入tempc中。
 通过mycnt(BiTreeNode *T)找到T节点的分别找到左子树和右子树的最大的深度和该深度的叶子节点。并通过递归调用通过mycnt(BiTreeNode *T)找到这棵树每一个节点这样的值。最终找到所有节点的(左子树的最大深度+右子树的最大深度)的最大值,并输出这个最大值和两个叶子节点。

本题容易错的地方为:
(1) 这两个节点的最大距离不一定经过祖宗节点。
(2)当这棵树的只有一个根节点时,是没有最大距离的节点的;但是,最大距离的节点是中是有可能有根节点的。
(3)每次调用完preOrder后要将maxHeight更新为0。

代码

#include 
#include 
#include 
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;			//标识建树字符串的当前字符位置
	BiTreeNode * CreateTree(BiTreeNode *T);//建树私有函数
    int maxHeight;
    int maxdis;
	void preOrder(BiTreeNode *T, int height);
    void mycnt(BiTreeNode *T);
    char leftc, rightc, tempc;
public:
	BiTree():root(NULL) {};	
	void Create(string vArray);	//建树公有接口,参数是特定的先序遍历字符串
	void preOrder();
    void mycnt();
};
//二叉树公有接口的实现
void BiTree::Create(string vArray) 
{	pos=0;
    maxHeight = 0;
    maxdis = 0;
	sTree.assign(vArray);	//把参数保存到内部字符串
	root = CreateTree(NULL);	//建树成功后root指向根结点
}


//请完成上述类内部的私有函数实现
/********** Write your code here! **********/

BiTreeNode * BiTree :: CreateTree(BiTreeNode *T)
{
    if(sTree[pos] == '#') 
    {
        pos ++;
        return NULL;
    }
    
    BiTreeNode * p = new BiTreeNode();
    p->data = sTree[pos];
    pos ++;
    p->leftChild = CreateTree(p);
    p->rightChild = CreateTree(p);
    return p;
}



void BiTree::  preOrder(BiTreeNode *T, int height)
{
    if(T->leftChild == NULL && T->rightChild == NULL)
    {
        if(height > maxHeight)
        {
            maxHeight = height;
            tempc = T->data;
        }
    }
    if(T->leftChild != NULL)  preOrder(T->leftChild, height + 1);
    if(T->rightChild != NULL) preOrder(T->rightChild, height + 1);
    
}

void BiTree :: mycnt()
{
    mycnt(root);
    if(maxdis)  cout << maxdis << ":" << leftc << " " << rightc << endl;
    else cout << maxdis << ":" << endl; 
}

void BiTree :: mycnt(BiTreeNode *T)
{
    if(T == NULL) return;
    int distance  = 0;
    char a = 'A', b = 'A';
    if(T->leftChild) 
    {
        preOrder(T->leftChild,1);
        a = tempc;
    }
    distance += maxHeight;
    maxHeight = 0;
    if(T->rightChild)
    {
        preOrder(T->rightChild,1);
        b = tempc;
    }
    distance += maxHeight;
    maxHeight = 0;

    if(distance > maxdis)
    {
        maxdis = distance;
        leftc = a;
        rightc = b;
    }

    mycnt(T->leftChild);
    mycnt(T->rightChild);

}


/*******************************************/
//主函数
int main()
{	int t;
	string vArray;
	cin>>t;
	while(t--)
	{	cin>>vArray;
		BiTree myTree;
		myTree.Create(vArray);
        
        myTree.mycnt();
	}
	return 0;
}

你可能感兴趣的:(算法,c++,数据结构)