【数据结构之二叉树系列】层序遍历

前言

前面我们学习的几种遍历方式主要有:前序遍历,中序遍历,层序遍历。这几种遍历方式都是采用递归进行实现的,而今天学习的层序遍历采取的是非递归的方式进行实现,主要是迭代的方式进行实现,同时需要使用队列结构进行辅助实现。

层序遍历

层序遍历其实也可以称为广度优先遍历,就是只按照顺序依次往下进行遍历的过程。

层序遍历的思想:利用一个队列结构进行辅助实现,首先判断对应的树是否为空树,如果为空树,则直接返回,如果不为空树,则先将根节点的值入队列,进行循环遍历,当队列不为空时,先取出队头元素,再将队头元素出队列,此时可以先访问取出的队头元素中存储的值,再判断队头元素是否存在左右子树,若存在左子树,则将左子树入队列,若存在右子树,则将右子树入队列。再进行下一轮循环

  • 代码实现
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

// 树的结构
typedef int TreeDataType;

// 树的结点
typedef struct TreeNode
{
	TreeDataType val;
	struct TreeNode* left;
	struct TreeNode* right;
};


typedef TreeNode* QDataType;

// 定义队列中结点的结构
typedef struct QueueNode
{
	QDataType data;
	struct QueueNode* next;
}QueueNode;

typedef struct Queue
{
	QueueNode* front;
	QueueNode* tail;
}Queue;


void QueueInit(Queue* q);
void QueuePush(Queue* q, QDataType val);
QDataType QueueFront(Queue* q);
bool QueueEmpty(Queue* q);
void QueueDestroy(Queue* q);
void QueuePop(Queue* q);





// 层序遍历
void LevelOrder(TreeNode* root)
{
	if (root == NULL)
	{
		// 空树
		return;
	}
	// 非空树
	// 将根节点入队列

	// 创建一个队列
	Queue q;// 创建队列
	QueueInit(&q);// 对队列进行初始化
	QueuePush(&q, root);// 将根节点的值先插入队列

	while (!QueueEmpty(&q))
	{
		// 当队列不为空的时候需要进行遍历处理‘
		TreeNode* front = QueueFront(&q);
		QueuePop(&q);
		// 判断取到的结点是否存在左右子树
		if (front->left)
		{
			QueuePush(&q, front->left);
		}

		if (front->right)
		{
			QueuePush(&q, front->right);
		}

		// 从队列中取到的值一定是不为空的
		// 访问取到的数据
		printf("%d ", front->val);
	}
	printf("\n");
	QueueDestroy(&q);

}

层序遍历的应用:判断一棵树是否为完全二叉树

bool TreeComplete(TreeNode* root)
{
	if (root == NULL)
	{
		return true;
	}

	// 非空树
	// 创建队列
	Queue q;
	QueueInit(&q);
	QueuePush(&q, root);
	while (!QueueEmpty(&q))
	{
		// 取队头元素
		TreeNode* front = QueueFront(&q);
		QueuePop(&q);
		if (front == NULL)
		{
			break;
		}
		QueuePush(&q,front->left);
		QueuePush(&q,front->right);
	}
	// 当程序走到这里,说明遇到了NULL
	while (!QueueEmpty(&q))
	{
		TreeNode* front = QueueFront(&q);
		QueuePop(&q);
		// 遇到非空的结点,说明在前面遇到的空结点是在非空结点前面出现,则说明该树不是完全二叉树
		if (front)
		{
			QueueDestroy(&q);
			return false;
		}
	}
	// 如果上述中没有访问非空结点,则说明第一次遇到的空结点就已经访问完所有的非空结点
	QueueDestroy(&q);
	return true;

}

思路分析:

使用一个队列结构进行辅助实现,思想与层序遍历差不多,只不过这道题中,空树仍然需要进队列,当第一次遍历到空结点的时候,结束第一个循环。接着遍历队列中的结点,如果遍历到非空结点,则说明上面的空结点存在于有效结点之间,则该树不是完全二叉树。如果没有遍历到非空,则说明第一次遍历到的空结点是在有效结点之后,说明该树是完全二叉树。

  • 13
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
叉树的层序遍历是一种按照从上到下、从左到右的顺序访问二叉树节点的方法。通过层序遍历,我们可以逐层遍历二叉树的节点,并在遍历过程中进行判断,从而确定二叉树是否为完全二叉树层序遍历是一种广度优先搜索的遍历方式,适用于树结构。通过利用队列实现层序遍历,我们可以按照从上到下、从左到右的顺序逐层遍历树中的节点。具体实现方法如下: ```python class TreeNode: def __init__(self, val=0, left=None, right=None): self.val = val self.left = left self.right = right def levelOrder(root: TreeNode) -> List[List[int]]: if not root: return [] res = [] queue = [root] while queue: level = [] for i in range(len(queue)): node = queue.pop(0) level.append(node.val) if node.left: queue.append(node.left) if node.right: queue.append(node.right) res.append(level) return res ``` 以上代码中,我们定义了一个`TreeNode`类来表示二叉树的节点,`levelOrder`函数用于实现二叉树层序遍历。在函数中,我们首先判断根节点是否为空,如果为空则直接返回空列表。然后定义一个`res`列表来存储遍历结果,定义一个`queue`队列来存储待遍历的节点。接下来,我们使用一个`while`循环来遍历整个二叉树。在每一层遍历中,我们定义一个`level`列表来存储当前层的节点值,然后使用一个`for`循环来遍历当前层的所有节点。在循环中,我们首先弹出队列中的第一个节点,并将其值加入到`level`列表中。然后判断该节点是否有左右子节点,如果有则将其左右子节点加入到队列中。最后将`level`列表加入到`res`列表中,表示当前层的遍历已经完成。最终返回`res`列表即可。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值