问题描述:已知二叉树的深度为根节点到最远叶子节点的最长路径上的节点数,其中叶子节点是指没有子节点的节点。请给出一种算法来计算一个二叉树的最大深度,描述并给出伪代码。(说明:输入为二叉树的根节点。)
最常见的一种算法:
int TreeDepth(TreeNode* pRoot)
{ if(pRoot == NULL ) return 0;
return max(TreeDepth(pRoot->left), TreeDepth(pRoot->right)) + 1; }
利用递归的方法,不断从根节点往下递归求子树的深度,直到递归到叶。
该算法需要递归n+m次,n是总节点数,m是叶数,算法总体简介美观,时间复杂度为O(n+n/2)=O(n),但是递归函数栈开销较大,所以尝试用迭代的方法对其改写。
参考层次遍历的方式:
上面的层次遍历算法,使用辅助队列,从根节点开始,从上往下从左往右,依次让每一层的节点入列,然后访问。
使用这个循环求树的深度,可以引入深度变量depth;每遍历一层出队count个元素,depth++;count为每一层的节点数。每层节点数通过上层所有节点是否有左右孩子判断。
算法实现:
template <typename T>
int TreeDepth(BitNode<T> *&root)
{
if (root == NULL) return 0;
queue<BitNode<T>> Q;
Q.push(*root);
int depth = 0, count = 1,nextCount = 0; //深度,当前层结点数,下一层结点数
BitNode<T> *temp;
while (!Q.empty()) //在队列变空前反复迭代
{
depth++; //每进入一次循环,就代表开始进入下一层
for (int i = 0; i < count; i++) //改层有count个节点
//循环count次,会有count次Q.pop
{
temp=&Q.front(); //取出队首节点
Q.pop();
if (temp->lchild!=NULL) { //添加非空结点,并标记下层节点数+1
Q.push(*temp->lchild);
nextCount++;
}
if (temp->rchild!=NULL) {
Q.push(*temp->rchild);
nextCount++;
}
}
count = nextCount; //到下一层,count更新
nextCount = 0;
}
return depth;
}
该算法也是把所有节点遍历了一次,时间复杂度为O(n),较之递归实现多了辅助队列的复杂度,但是总体的时间、空间复杂度都有节省。
测试:
Main函数:
BinaryTree<int> tree;
cout << "输入数构造序列" << endl;
tree.CreateTree(tree.root);
cout << "树的深度:"<<TreeDepth(tree.root)<<endl;
输出:
参考博客: