每日一题(72) - 分层遍历二叉树

题目来自编程之美

题目(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;
} 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值