题目来自编程之美
题目(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;
}