二叉查找树的层序遍历

二查找树层序遍历的思路是沿着树中同一深度的节点进行遍历

难点在于如何在同层节点之间移动,一般方法为预先处理,即在处理父节点时将子节点信息保存,而且要注意需要从左向右顺序遍历,很自然的使用FIFO的队列就可以啦~

由于我们在处理当前层时预先将下一层的节点入列,那我们如何知道什么时候处理完当前层了呢?

我们可以在每次处理完当前层时放置一个结束的标识,因为队列节点的键值为TreeNode *,所以我们可以将NULL值当作结束标志在每处理完一层后将其入列~

代码如下:

void PrintNodeByLevel1(Tree T)
{
	Queue Q = CreateQueue();
	Tree Temp = T;
	MemberType mTemp;  //typedef TreeNode * MemberType
	Enqueue(T, Q);     //将根节点入列
	Enqueue(NULL, Q);
	while (!IsEmpty(Q))
	{
		while ((mTemp = Dequeue(Q))!=NULL)
		{//每次迭代将首元素出列
			printf("%d ", mTemp->Element);
			//将当前访问的元素的子节点入列
			if (mTemp->Left)
				Enqueue(mTemp->Left, Q);
			if (mTemp->Right)
				Enqueue(mTemp->Right, Q);
		}
		printf("\n");
		if (!IsEmpty(Q))         //注意!如果不检查队列是否为空就将NULL入列,会造成死循环!
		<span style="white-space:pre">	</span>Enqueue(NULL, Q);	//将空值入列代表作为当前行结束标识
	}
}


还有第二种层序遍历的方法,是用C++自带的vector容器替代队列,利用了vector容器的自动扩充的能力,这次并没有使用NULL值作为结束标识,而是使用两个int变量,一个指向当前处理的元素,一个指向当前层的尾后位置(有点乱。。)

代码如下:

void PrintNodeByLevel2(Tree T)
{
	vector<TreeNode *> vec;
	int cur = 0;//当前节点
	int last = 1;//当前层尾后游标
	Tree Temp = T;
	vec.push_back(Temp);
	while (cur<vec.size())//当上次迭代中没有子节点入列,说明当前层为叶子层
	{
		last = vec.size();//将last游标设置在行尾
		while (cur < last)
		{
			printf("%d ",vec[cur]->Element);
			//当前访问元素的子节点入列
			if (vec[cur]->Left)
				vec.push_back(vec[cur]->Left);
			if (vec[cur]->Right)
				vec.push_back(vec[cur]->Right);
			++cur;//当前访问结点后移
		}
		printf("\n");
	}
}

这两个方案并没有谁优谁劣之分,都着O(N)的空间复杂度以及O(N^2)的时间复杂度,在结束标识问题上第一个方案需要占用队列空间,第二个方案使用两个游标,差别不大。

    原文作者:二叉查找树
    原文地址: https://blog.csdn.net/pililipalalar/article/details/51984317
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞