求二叉树的深度和宽度

// 求二叉树的深度和宽度.cpp : 定义控制台应用程序的入口点。
<pre name="code" class="cpp">#include <iostream>
#include <queue>
using namespace std;


struct BTNode
{
	char m_value;
	BTNode *m_left;
	BTNode *m_right;
};


//先序创建二叉树
void CreatBTree(BTNode *&root)
{ 
	char nValue = 0;
	cin >> nValue;
	if ('#' == nValue)
	{
		return;
	}
	else
	{
		root = new BTNode();
		root->m_value = nValue;
		CreatBTree(root->m_left);
		CreatBTree(root->m_right);
	} 
}


//求二叉树的深度
int GetDepth(BTNode *pRoot)
{
	if (pRoot == NULL)
	{
		return 0;
	}


	// int nLeftLength = GetDepth(pRoot->m_left);
	// int nRigthLength = GetDepth(pRoot->m_right);
	// return nLeftLength > nRigthLength ? (nLeftLength + 1) : (nRigthLength + 1);


	return GetDepth(pRoot->m_left) > GetDepth(pRoot->m_right) ? 
		(GetDepth(pRoot->m_left) + 1) : (GetDepth(pRoot->m_right) + 1);
}


//求二叉树的宽度
int GetWidth(BTNode *pRoot)   //方法一
{
	if (pRoot == NULL)
	{
		return 0;
	}


	int nLastLevelWidth = 0;//记录上一层的宽度
	int nTempLastLevelWidth = 0;
	int nCurLevelWidth = 0;//记录当前层的宽度
	int nWidth = 1;//二叉树的宽度
	queue<BTNode *> myQueue;
	myQueue.push(pRoot);//将根节点入队列
	nLastLevelWidth = 1;
	BTNode *pCur = NULL;


	while (!myQueue.empty())//队列不空
	{
		nTempLastLevelWidth = nLastLevelWidth;
		while (nTempLastLevelWidth != 0)
		{
			pCur = myQueue.front();//取出队列头元素
			myQueue.pop();//将队列头元素出对


			if (pCur->m_left != NULL)
			{
				myQueue.push(pCur->m_left);
			}


			if (pCur->m_right != NULL)
			{
				myQueue.push(pCur->m_right);
			}


			nTempLastLevelWidth--;
		}


		nCurLevelWidth = myQueue.size();
		nWidth = nCurLevelWidth > nWidth ? nCurLevelWidth : nWidth;
		nLastLevelWidth = nCurLevelWidth;
	}


	return nWidth;
}
int GetWidth2(BTNode *head)  //方法二
{


	if (head == NULL)  
	{  
		return 0;  
	}  


	int nTempLastLevelWidth = 0;  
	int nWidth = 1;//二叉树的宽度  
	queue<BTNode *> myQueue;  
	myQueue.push(head);//将根节点入队列    
	myQueue.push(NULL);
	BTNode *pCur = NULL;  


	while (!myQueue.empty())//队列不空  
	{  
		pCur = myQueue.front();//取出队列头元素  
		while (pCur != NULL)  
		{   
			myQueue.pop();//将队列头元素出对  
			if (pCur->m_left != NULL)  
			{  
				myQueue.push(pCur->m_left);  
			}  


			if (pCur->m_right != NULL)  
			{  
				myQueue.push(pCur->m_right);  
			}  
			pCur = myQueue.front();//取出队列头元素 
		} 
		myQueue.pop();//将队列头元素NULL出对  


		nTempLastLevelWidth = myQueue.size();  //新增加的一层个数
		if (nTempLastLevelWidth>0)
		{
			myQueue.push(NULL);
		}
		nWidth = nTempLastLevelWidth > nWidth ? nTempLastLevelWidth : nWidth;  

	}  


	return nWidth;  




}

int main()
{
	BTNode *pRoot = NULL;
	CreatBTree(pRoot);
	cout << "二叉树的深度为:" << GetDepth(pRoot) << endl;
	cout << "二叉树的宽度为:" << GetWidth(pRoot) << endl;
	system("pause");
	return 0;
}


 
 

说明:

   1.概念解析:


宽度:节点的叶子数
深度:节点的层数

算法上有所谓的"宽度优先算法"和"深度优先算法"

二叉树的宽度定义为具有最多结点数的层中包含的结点数。
求二叉树的深度和宽度_第1张图片


比如上图中,
第1层有1个节点,
第2层有2个节点,
第3层有4个节点,
第4层有1个节点,
可知,第3层的结点数最多
所以这棵二叉树的宽度就是4

2. 求解二叉树根节点的深度就是比较左右子树的深度。因此根节点的深度=左右子树深度的最大值+1;

因此可以使用递归算法。在使用中实际上就是后序遍历.

3.求解宽度,何为二叉树的宽度,即为含有节点个数最多也就是最长的那一层的长度。因此我们可以想到层次遍历。使用queue。

我们需要理清每层的节点分别是谁?可以有两种办法,一种就是在插入新节点的时候计算长度,等到下一次遍历时清除掉上一层的节点,依据个数。

二、就是在每一层后面插入一个NULL,最后一层没有数据,可以不插。这样一层层遍历,遇到NULL,表明到达结尾。然后开始下一层遍历。


参考文献:

 1. http://blog.csdn.net/htyurencaotang/article/details/12406223

 2. http://blog.csdn.net/wuzhekai1985/article/details/6730352

你可能感兴趣的:(C++)