二叉樹中最大/最小深度與葉子數


首先我們需要了解什么是“樹的深度”和“樹的葉子”。

樹的葉子:一棵樹當中沒有子結點(即度為0)的結點稱為葉子結點,簡稱“葉子”。 葉子是指度為0的結點,又稱為終端結點。

樹的深度:樹中最大的結點層。舉個例子:你爺爺是根節點,你爸爸叔叔是你爺爺的左/右孩子,你是你爸爸的左孩子。那么你爸爸叔叔的深度是2,你的深度是3。(夠通俗吧?)

首先我們來求樹的葉子數量,葉子的特征是沒有子節點。

思路:

1、判斷該節點左、右孩子是否都等於空,如果是:葉子數加一;如果不是:入棧

2、該節點等該節點的左子節點,重復步驟1,直到該節點等於空,執行步驟3。

3、如果棧非空:零時指針指向棧頂元素的右子節點,刪除棧頂元素;如果棧為空:執行完畢,退出。

具體代碼如下:

TEMPTYPE int CBinaryTree<type>::Leaves()
{
	auto pStack = new stack<LPTREENODE>;
	auto nLeaves = 0, nCount = 0, nSize = Size();
	auto pTempTree = m_pTree;

	while (true)
	{
		while (pTempTree)
		{
			if (!pTempTree->m_pLeftChild && !pTempTree->m_pRightChild)++nLeaves;
			else pStack->push(pTempTree);

			pTempTree = pTempTree->m_pLeftChild;
		}
		if (!pStack->empty()){
			pTempTree = pStack->top()->m_pRightChild;
			pStack->pop();
		}else break;
	}
	delete pStack;
	return nLeaves;
}

求葉子的數量搞定了,那么我們來求最大/最小深度。

思路:

1、根節點添加到隊列中

2、如果隊列隊列不為空:深度加一,執行第3步;

3、記錄下隊列的長度(重要,遍歷用的),遍歷隊列的長度(記錄下的那個長度),定義一個臨時指針指向隊列的底部,從隊列中刪除底部。執行第4步。

4、判斷臨時指針指向的節點是否是葉子節點,如果是:最小深度執行完畢,返回;否則:執行第5步;(如果求最大深度,跳過第4步,執行第5步)

5、左、右孩子添加到隊列。

6、遍歷完畢,重復執行步驟2。

具體代碼如下:

// 求最小深度  使用棧
TEMPTYPE int CBinaryTree<type>::MinDepth()
{
        stack<LPTREENODE> q1, q2;
	int nCount = 0;
	if (m_pTree)q1.push(m_pTree);
	while (!q1.empty() || !q2.empty())
	{
		if (!q1.empty())
		{
			nCount++;
			while (!q1.empty())
			{
				auto pTemp = q1.top();
				q1.pop();
				if (!pTemp->m_pLeftChild && !pTemp->m_pRightChild)return nCount;
				if (pTemp->m_pLeftChild)q2.push(pTemp->m_pLeftChild);
				if (pTemp->m_pRightChild)q2.push(pTemp->m_pRightChild);
			}
		}

		if (!q2.empty())
		{
			nCount++;
			while (!q2.empty())
			{
				auto pTemp = q2.top();
				q2.pop();
				if (!pTemp->m_pLeftChild && !pTemp->m_pRightChild)return nCount;
				if (pTemp->m_pLeftChild)q1.push(pTemp->m_pLeftChild);
				if (pTemp->m_pRightChild)q1.push(pTemp->m_pRightChild);
			}
		}
	}
	return nCount;
}
// 求最大深度  使用棧
TEMPTYPE int CBinaryTree<type>::MinDepth()
{
        stack<LPTREENODE> q1, q2;
	int nCount = 0;
	if (m_pTree)q1.push(m_pTree);
	while (!q1.empty() || !q2.empty())
	{
		if (!q1.empty())
		{
			nCount++;
			while (!q1.empty())
			{
				auto pTemp = q1.top();
				q1.pop();
				if (pTemp->m_pLeftChild)q2.push(pTemp->m_pLeftChild);
				if (pTemp->m_pRightChild)q2.push(pTemp->m_pRightChild);
			}
		}

		if (!q2.empty())
		{
			nCount++;
			while (!q2.empty())
			{
				auto pTemp = q2.top();
				q2.pop();
				if (pTemp->m_pLeftChild)q1.push(pTemp->m_pLeftChild);
				if (pTemp->m_pRightChild)q1.push(pTemp->m_pRightChild);
			}
		}
	}
	return nCount;
}

  

  

 

// 求最小深度   使用隊列   m_pTree是根節點
TEMPTYPE int CBinaryTree<type>::MinDepth()
{
	queue<LPTREENODE> que;
	int nCount = 0;
	if (m_pTree)que.push(m_pTree);
	while (!que.empty())
	{
		nCount++;
		int nSize = que.size();
		while (nSize--)
		{
			auto pTemp = que.front();
			que.pop();

			if (!pTemp->m_pLeftChild && !pTemp->m_pRightChild)return nCount;
			if (pTemp->m_pLeftChild)que.push(pTemp->m_pLeftChild);
			if (pTemp->m_pRightChild)que.push(pTemp->m_pRightChild);
		}
	}
	return nCount;
}

  

// 求最大深度   使用隊列   m_pTree是根節點
TEMPTYPE int CBinaryTree<type>::MinDepth()
{
	queue<LPTREENODE> que;
	int nCount = 0;
	if (m_pTree)que.push(m_pTree);
	while (!que.empty())
	{
		nCount++;
		int nSize = que.size();
		while (nSize--)
		{
			auto pTemp = que.front();
			que.pop();

			if (pTemp->m_pLeftChild)que.push(pTemp->m_pLeftChild);
			if (pTemp->m_pRightChild)que.push(pTemp->m_pRightChild);
		}
	}
	return nCount;
}

  

 

 

 

 

注意:上述代碼中所有m_pTree都是根節點


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM