首先我们需要了解什么是“树的深度”和“树的叶子”。
树的叶子:一棵树当中没有子结点(即度为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都是根节点