求二叉树中最远节点的距离,我们首先要对最远距离有清晰的认识,最远距离分为以下三类情况
因此我们在计算距离时总要与前一次的距离作比较,只有当此次左右距离之和大于max值才更改max的值,我们可以使用后续遍历来计算最远距离,此时时间复杂度为O(N),使用前序遍历也是可以的,但时间复杂度为O(N*N),综合比较我们选择后续遍历。实现方法写在一个搜索树中了。
代码如下:
#pragma once
#include<iostream>
#include<stack>
#include<queue>
using namespace std;
//寻找二叉树中距离最远的两个节点
//使用递归,保存上一次最远距离,和这次节点的左右最长距离比较,取长的距离作为下次递归的长度
//使用后序遍历和前序遍历都可以结局此问题,但是前序遍历时间复杂度为O(N*N),而后序遍历的时间复杂度为O(N),因此选择后续遍历
template<class T>
struct BSNode
{
int key;
BSNode* left;
BSNode* right;
BSNode* parent;
BSNode(T value) :
key(value)
, left(NULL)
, right(NULL)
, parent(NULL)
{}
};
template<class T>
class BSTree
{
typedef BSNode<T> Node;
public:
BSTree() :
_root(NULL)
{}
~BSTree()
{}
private:
int TreeDepth(Node* root)
{
if (root == NULL)
return 0;
int nLeftDepth = TreeDepth(root->left);
int nRightDepth = TreeDepth(root->right);
return (nLeftDepth>nRightDepth) ? (nLeftDepth + 1) : (nRightDepth + 1);
}
int RFindLongDistance(Node* root,int &max,int &LeftLen,int &RightLen)
{
if (root == NULL)
{
return max;
}
RFindLongDistance(root->left,max,LeftLen,RightLen);
RFindLongDistance(root->right,max,LeftLen,RightLen);
LeftLen = TreeDepth(root->left);
RightLen = TreeDepth(root->right);
return max > (LeftLen + RightLen) ? max : LeftLen + RightLen;
}
public:
size_t FindLongerDistance()
{
if (_root == NULL)
{
return 0;
}
int MaxLen = 0;
int LeftLen = 0;
int RightLen = 0;
return RFindLongDistance(_root,MaxLen,LeftLen,RightLen) + 1;
}
public:
void Insert(T key)
{
Node* newnode = new Node(key);
if (_root == NULL)
{
_root = newnode;
}
else
{
Node* cur = _root;
Node* parent = NULL;
while (cur)
{
parent = cur;
if (key > cur->key)
{
cur = cur->right;
}
else if (key < cur->key)
{
cur = cur->left;
}
else
{
return;
}
}
if (parent->key > key)
{
parent->left = newnode;
}
else
{
parent->right = newnode;
}
newnode->parent = parent;
}
}
void Print()
{
if (_root == NULL)
{
return;
}
_Print(_root);
}
void _Print(Node* cur)
{
if (cur == NULL)
{
return;
}
else if (cur->left)
{
_Print(cur->left);
}
cout << cur->key << " ";
if (cur->right)
{
_Print(cur->right);
}
}
Node* Find(int key)
{
Node* cur = _root;
while (true)
{
if (cur->key > key)
{
cur = cur->left;
}
else if (cur->key < key)
{
cur = cur->right;
}
else
{
return cur;
}
}
return NULL;
}
private:
BSNode<T>* _root;
};
二叉树如下:
结果如下:
二叉树如下:
结果如下:
二叉树如下:
结果如下: