题目来自编程之美
题目(1)
举例
思路:很容易得到层序遍历的序列,这里重点在于怎么确定每层结点的结束位置。
思路(1)在处理本层结点时,使用一个游标指向本层最后一个结点的后一个位置。
代码:
struct BTNode { int m_nData; BTNode* m_pLeft; BTNode* m_pRight; }; void LevelOrder(BTNode* pRoot) { assert(pRoot); int nCur = 0; int nLast = 0; BTNode* pCurNode = NULL; vector<BTNode*> vArrLevel; vArrLevel.push_back(pRoot); while(nCur < vArrLevel.size()) { nLast = vArrLevel.size(); while(nCur < nLast) { pCurNode = vArrLevel[nCur++]; cout<<pCurNode->m_nData<<" "; if (pCurNode->m_pLeft) { vArrLevel.push_back(pCurNode->m_pLeft); } if (pCurNode->m_pRight) { vArrLevel.push_back(pCurNode->m_pRight); } } cout<<endl; } }
思路(2)使用一个分隔符NULL表示本层结束,输出换行。
void LevelOrder(BTNode* pRoot,int nLevel) { assert(pRoot && nLevel > -1); int nCur = 0; vector<BTNode*> vArrLevel; vArrLevel.push_back(pRoot); vArrLevel.push_back(NULL); while(vArrLevel[nCur] != NULL)//数组中最后俩元素肯定为NULL { while(vArrLevel[nCur] != NULL) { cout<<vArrLevel[nCur]->m_nData<<" "; if (vArrLevel[nCur]->m_pLeft) { vArrLevel.push_back(vArrLevel[nCur]->m_pLeft); } if (vArrLevel[nCur]->m_pRight) { vArrLevel.push_back(vArrLevel[nCur]->m_pRight); } nCur++; } vArrLevel.push_back(NULL);//本层结束 nCur++;//跳过上一层的NULL cout<<endl; } }
思路(3)使用一个变量记录每层元素个数。
struct BTNode { int m_nData; BTNode* m_pLeft; BTNode* m_pRight; }; void LevelOrder(BTNode* pRoot,int nLevel) { assert(pRoot && nLevel > -1); int nCur = 0; int nCurCount = 0; int nLastCount = 1; vector<BTNode*> vArrLevel; vArrLevel.push_back(pRoot); while(nCur < vArrLevel.size())//数组中最后俩元素肯定为NULL { while(nLastCount) { cout<<vArrLevel[nCur]->m_nData<<" "; if (vArrLevel[nCur]->m_pLeft) { vArrLevel.push_back(vArrLevel[nCur]->m_pLeft); nCurCount++; } if (vArrLevel[nCur]->m_pRight) { vArrLevel.push_back(vArrLevel[nCur]->m_pRight); nCurCount++; } nLastCount--; nCur++; } nLastCount = nCurCount; nCurCount = 0; cout<<endl; } }题目(2)
思路:只需要题目(1)中稍微改动下,到目标层就直接输出即可。实现的思路也很多,这里使用思路(1)实现。
代码:
struct BTNode { int m_nData; BTNode* m_pLeft; BTNode* m_pRight; }; int LevelOrder(BTNode* pRoot,int nLevel) { assert(pRoot && nLevel > -1); int nCur = 0; int nLast = 0; int nCurLevel = 0; BTNode* pCurNode = NULL; vector<BTNode*> vArrLevel; vArrLevel.push_back(pRoot); while(nCurLevel < nLevel && nCur < vArrLevel.size()) { nLast = vArrLevel.size(); while(nCur < nLast) { pCurNode = vArrLevel[nCur++]; if (pCurNode->m_pLeft) { vArrLevel.push_back(pCurNode->m_pLeft); } if (pCurNode->m_pRight) { vArrLevel.push_back(pCurNode->m_pRight); } } nCurLevel++; } //输出第nLevel层结点 if (nCurLevel != nLevel) { cout<<"本层无结点!"<<endl; return 0; } nLast = vArrLevel.size(); while(nCur < nLast) { cout<<vArrLevel[nCur++]->m_nData<<" "; } cout<<endl; return 1; }
题目(3)输入如下顺序
思路:可以使用递归实现。每次递归输出一层。
代码:
void LevelOrder(BTNode* pRoot,vector<BTNode*>& vArrLevel,int& nCur) { assert(pRoot); int nStart = nCur; int nEnd = 0; BTNode* pCurNode = NULL; while(nCur < vArrLevel.size()) { nEnd = vArrLevel.size(); while(nCur < nEnd) { pCurNode = vArrLevel[nCur++]; if (pCurNode->m_pLeft) { vArrLevel.push_back(pCurNode->m_pLeft); } if (pCurNode->m_pRight) { vArrLevel.push_back(pCurNode->m_pRight); } } LevelOrder(pRoot,vArrLevel,nCur); //输出 for (int i = nStart;i < nEnd;i++) { cout<<vArrLevel[i]->m_nData<<" "; } cout<<endl; } } void LevelOrder(BTNode* pRoot) { assert(pRoot); int nCur = 0; vector<BTNode*> vArrLevel; vArrLevel.push_back(pRoot); LevelOrder(pRoot,vArrLevel,nCur); }题目(4)根据二叉树,输出一下格式的数据
思路(1):和题目(3)的思路一样,输出时反序输出
代码:
void LevelOrder(BTNode* pRoot,vector<BTNode*>& vArrLevel,int& nCur) { assert(pRoot); int nStart = nCur; int nEnd = 0; BTNode* pCurNode = NULL; while(nCur < vArrLevel.size()) { nEnd = vArrLevel.size(); while(nCur < nEnd) { pCurNode = vArrLevel[nCur++]; if (pCurNode->m_pLeft) { vArrLevel.push_back(pCurNode->m_pLeft); } if (pCurNode->m_pRight) { vArrLevel.push_back(pCurNode->m_pRight); } } LevelOrder(pRoot,vArrLevel,nCur); //输出 for (int i = nEnd - 1;i >= nStart;i--) { cout<<vArrLevel[i]->m_nData<<" "; } cout<<endl; } } void LevelOrder(BTNode* pRoot) { assert(pRoot); int nCur = 0; vector<BTNode*> vArrLevel; vArrLevel.push_back(pRoot); LevelOrder(pRoot,vArrLevel,nCur); }思路(2):和题目(3)的思路一样,但是孩子入队时,先右孩子后左孩子,之后输出时正序输出
代码:
void LevelOrder(BTNode* pRoot,vector<BTNode*>& vArrLevel,int& nCur) { assert(pRoot); int nStart = nCur; int nEnd = 0; BTNode* pCurNode = NULL; while(nCur < vArrLevel.size()) { nEnd = vArrLevel.size(); while(nCur < nEnd) { pCurNode = vArrLevel[nCur++]; if (pCurNode->m_pRight) //右孩子先进去,左孩子后进去 { vArrLevel.push_back(pCurNode->m_pRight); } if (pCurNode->m_pLeft) { vArrLevel.push_back(pCurNode->m_pLeft); } } LevelOrder(pRoot,vArrLevel,nCur); //输出 for (int i = nStart;i < nEnd;i++) { cout<<vArrLevel[i]->m_nData<<" "; } cout<<endl; } } void LevelOrder(BTNode* pRoot) { assert(pRoot); int nCur = 0; vector<BTNode*> vArrLevel; vArrLevel.push_back(pRoot); LevelOrder(pRoot,vArrLevel,nCur); }
思路(3):得到层次遍历次序,每层之间使用NULL分开,之后逆序输出即可。
代码:
void LevelOrder(BTNode* pRoot) { assert(pRoot); int nCur = 0; vector<BTNode*> vArrLevel; vArrLevel.push_back(pRoot); vArrLevel.push_back(NULL);//本层结束 while(vArrLevel[nCur] != NULL)//数组中最后俩元素肯定为NULL { while(vArrLevel[nCur] != NULL) { if (vArrLevel[nCur]->m_pLeft) { vArrLevel.push_back(vArrLevel[nCur]->m_pLeft); } if (vArrLevel[nCur]->m_pRight) { vArrLevel.push_back(vArrLevel[nCur]->m_pRight); } nCur++; } vArrLevel.push_back(NULL);//本层结束 nCur++;//跳过上一层的NULL } //逆序输出 vArrLevel.pop_back(); vArrLevel.pop_back(); nCur = vArrLevel.size(); for (int i = nCur - 1;i >= 0;i--) { if (vArrLevel[i] == NULL) { cout<<endl; } else { cout<<vArrLevel[i]->m_nData<<" "; } } cout<<endl; }