【408DS算法题】027基础-二叉树的层次遍历

Index

    • 题目
    • 分析实现
    • 总结

题目

给定二叉树的根节点root,写出函数实现对二叉树的层次遍历。


分析实现

二叉树的层次遍历即广度优先遍历(BFS),其访问顺序,可以非常直观地看出。但二叉树本身的存储结构并不能直接实现层次遍历,常见的遍历方式是借助队列存储当前层的所有结点,思路如下:

  1. 将根节点root加入队列q
  2. 对于队列中每个结点cur,访问队首结点cur,将cur出队,再将cur的子节点加入q
  3. 重复2直到q为空

具体实现如下:

#include 

// 队列实现层次遍历
void levelOrder(BTNode* root) {
    if (root == NULL) 
		return;
    queue<BTNode*> q;
    q.push(root);
    
    while (!q.empty()) {
        BTNode* cur = q.front();
        q.pop();
        // 访问当前结点 e.g: cout<val<<' ';
        visit(cur);		
        if (cur->left != NULL)
            q.push(cur->left);
        if (cur->right != NULL)
            q.push(cur->right);
    }
}

这是常见的层次遍历写法,在此基础之上,还可以进行一点改进使得遍历过程更加灵活:

  1. 将根节点root加入队列q
  2. 记录当前q的元素个数n,执行n次 “访问cur,出队cur,加入cur子节点”
  3. 重复2直到q为空

此处最大的改动在于(2),改动前每一步(2)只会执行1次 “访问cur,出队cur,加入cur子节点”,改动后每一步(2)会直接执行n次 “访问cur,出队cur,加入cur子节点” ,这样每次执行(2)都固定对一层的结点进行操作并出队。

通过这种改进,可以很简单地分清每一层结点,使用实例如下:

// 分层输出的层次遍历
void levelOrder(BTNode* root) {
    if (root == NULL) 
        return;
    queue<BTNode*> q;
    q.push(root);
	// 定义变量记录当前层次
    int layer = 1;
    while (!q.empty()) {
        cout << "当前访问的层次为:" << layer << endl;
        layer++;
        // 定义变量记录当前层次结点个数
        int n = q.size();
        while (n--) {
            BTNode* cur = q.front();
            q.pop();
            cout << cur->val << " ";
            if (cur->left != NULL)
                q.push(cur->left);
            if (cur->right != NULL)
                q.push(cur->right);
        }
        cout << endl; // 换行以区分不同层次的节点
    }
}

总结

以上就是常用的使用队列实现层次遍历的实现,以及在此基础之上十分常用的改进。

代码中使用了c++的头文件,queue的常用操作如下:

queue<int> q;	// 定义一个存储int型元素的队列q

q.empty();	// return bool, 若q为空,返回true
q.size();	// return size_t, 返回q中元素个数,不会溢出的情况下经常存储于int变量中

q.push(x);	// 将元素x添加到队列尾部
q.pop();	// 将队首元素出队

q.front();	// 返回队首元素
q.back();	// 返回队尾元素

你可能感兴趣的:(算法,c++,数据结构,queue,层次遍历,考研,二叉树)