LeetCode二叉树的层序遍历

Posted xiao zhou

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode二叉树的层序遍历相关的知识,希望对你有一定的参考价值。

题目描述

题目分析

xxxx这道题,题目是“二叉树的层序遍历”,首先我们提取一下题目和题目内容的关键词。“二叉树”、“层序遍历”、“每一层值分别存储到一个vector”
(可能不同的人看的着重点不完全相同,我注意到的是以上三个)。二叉树的层序遍历还是比较好搞的,根据数据结构的基础知识,只要我们借助一个队列,利用队列的“先进先出”的特性,就能够很好的进行层序遍历。为了避免部分读者暂时不会代码实现,影响后面的问题分析和代码阅读。所以我先讲解一下如何借助队列实现二叉树的层序遍历
xxxx如果有想对二叉树有更深更全面的了解和学习的读者可以打开下面的链接学习:二叉树的深入学习

二叉树的层序遍历

首先看一下动图,了解怎么叫层序遍历

xxxx层序遍历需要借助队列,首先将头结点入队,然后出队访问出队的结点,如果该出队的结点有左孩子则左孩子入队;如果有右孩子则右孩子入队。再循环,出队得到一个节点,然后访问出队的结点,如果该出队的结点有左孩子则左孩子入队;如果有右孩子则右孩子入队……知道队列为空,则遍历结束。


代码实现

//二叉树结点的定义
/**
 * struct TreeNode {
 *	int val;
 *	struct TreeNode *left;
 *	struct TreeNode *right;
 * };
 */
void SequenceTraversal(TreeNode* root)
{
	queue<TreeNode*> q;
	q.push(root)
	while(q.size())
	{
		TreeNode node = q.front();
		VisitNode(node);
		q.pop();
		if(node->left)
		{
			q.push(node->left);
		}
		if(node->right)
		{
			q.push(node->right);
		}
	}
}

xxxx明白了如何进行层序遍历,接下来我们继续进行本题的题目分析。
xxxx在“二叉树”、“层序遍历”、“每一层值分别存储到一个vector”这三个关键词中,我们已经解决了前两个关键词了,现在最重要的,也是我做这道题认为最困难的部分就是如何将每一层的数据分别存储。通过刚刚对层序遍历的认识,我们发现,他只能单一的存储数据,但是无法区分某一个属于第几层。因此就需要改进一下便于标识数据属于第几层。但是大体思路还是利用队列进行层序遍历。
xxxx我们发现在层序遍历的每个循环中,大体分为两个部分:1、处理一个结点。2、将被处理的结点的左右孩子入队
xxxx这就说明,我们在处理完一个结点后,就可以知道该结点有几个孩子。我们就可以将孩子的个数统计出来,这样我们处理一个孩子就将计数器-1,直到计数器为0,我么就知道了这个结点的孩子已经处理完成。
xxxx将一个结点扩展成一层结点。假设我们已知某一层有num个结点,由于层序遍历是一层一层遍历。于是当我们处理完这一层的num结点,计数器count就可以统计处这一层结点一共有几个孩子,孩子数量count就是下一层结点的个数。然后我们再把count赋值给num,这样就更新了下一层的结点个数,count就可以再次统计处下一层结点的孩子个数。这样一直循环,还是截止到队列为空,遍历结束。这样我们就能很好的知道每一层的结点个数。

代码实现

    vector<vector<int> > levelOrder(TreeNode* root) {
        // write code here
        if(root == nullptr)
            return {};
        vector<vector<int> > ret;
        queue<TreeNode*> q;
        //先将头结点入队
        q.push(root);
        //第一层只有头结点,所以num初始化为1
        int num = 1;
        //记录下一层结点数的计数器count初始化0
        int count = 0;
        //定义v,用于存储每一层的结果
        vector<int> v;
        while(q.size())
        {
        	//先从队中取出对头数据
            TreeNode* tmp = q.front();
            //处理该结点,将val插入到v中
            v.push_back(tmp->val);
            //pop掉之后count就减1,说明这一层处理完一个数据了
            q.pop();
            num--;
            //如果有左孩子,则入队
            if(tmp->left)
            {
                q.push(tmp->left);
                //count++,证明下一层结点数+1
                count++;
            }
            //如果有右孩子,则入队
            if(tmp->right)
            {
                q.push(tmp->right);
                //count++,证明下一层结点数+1
                count++;
            }
            //因为处理该层一个结点num-1,如果num==0,说明该层结点处理完毕,就要更新num,count
            if(num==0)
            {
                //将该层的结果push到二维数组中
                ret.push_back(v);
                vector<int> a;
                v = a;
                //该处理下一层了,下一层结点数就是count
                num = count;
                //count重新置为0
                count = 0;
            }
        }
        //循环结束,就可以返回vector<vector<int>>这个二维数组了
        return ret;
    }
};

总结

xxxx这道题考查的本质就是二叉树的层序遍历,其实二叉树的层序遍历本身不是一个特别难的知识点,只要实现过一次,基本就能很好的实现层序遍历。所以如果这题,没有要求分别返回每一层的数据结果,是不可能到达一个中等难度的。困难点就在于如何控制每一层的开始和停止。如何知道什么时候一层结束。那我们利用的方面有:1、层序遍历,就是一层一层的遍历;2、对于每个结点,我们都可以直接访问他们的左右孩子进行计数。
xxxx这道题大体就是这样。如果有好的解题方法或者我的方法有什么瑕疵错误,请在评论区指出。让我们互相学习,共同进步。谢谢大家!

以上是关于LeetCode二叉树的层序遍历的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode-102-二叉树的层序遍历

leetcode102二叉树的层序遍历

LeetCode第107题—二叉树的层序遍历II—Python实现

LeetCode第102题—二叉树的层序遍历—Python实现

leetcode-102二叉树的层序遍历

leetcode-二叉树的层序遍历-77