前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Day21-二叉树-二叉树的右视图

Day21-二叉树-二叉树的右视图

作者头像
BUPTrenyi
发布2019-07-15 17:03:10
6210
发布2019-07-15 17:03:10
举报
文章被收录于专栏:算法其实很好玩

一 唠嗑

我尽量加快进度,明天开始讲图。

二叉树没了?当然不是,难题后面会慢慢更的

二 上题

Q:给定一个二叉树,以从上到下的顺序,返回这个二叉树的右视图。

举例:还是昨天的二叉树

那么就要返回数组[1,5,6]

如果此时把6节点拿掉,就要返回[1,5,4]

三 冷静分析

此处我们先复习一下二叉树的层次遍历

思路很简单,利用队列(FIFO的性质)

将二叉树根节点push进队列

在队列非空的情况下循环:

取出队头元素,并输出;

弹出刚刚输出的队头元素;

将队头的左子树push进队列(如果有左子树);

将队头的右子树push进队列(如果有右子树);

逻辑很简单,主要是利用了队列先进先出的性质来实现层次遍历。直接上代码

代码语言:javascript
复制
//
// Created by renyi on 2019-07-09.
//
#include <iostream>
#include <queue>
using namespace std;

struct TreeNode{
    int value;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int v) : value(v), left(NULL), right(NULL) {}
};

void levelTraversalPrint(TreeNode* root){
    queue<TreeNode*> q;
    q.push(root);
    while (!q.empty()){
        TreeNode* node = q.front();//取出队头元素
        printf("[%d]", node->value);
        q.pop();

        if (node->left){
            q.push(node->left);
        }

        if (node->right){
            q.push(node->right);
        }
    }
}

int main(){
    TreeNode a(1);//建立配图的二叉树
    TreeNode b(2);
    TreeNode c(5);
    TreeNode d(3);
    TreeNode e(4);
    TreeNode f(6);

    a.left = &b;
    a.right = &c;
    b.left = &d;
    b.right = &e;
    c.right = &f;

    levelTraversalPrint(&a);
    return 0;
}

那么对于这个二叉树,层次遍历的结果就应该是


回到题目本身,我们需要利用层次遍历的思想来解决它:

  1. 层次遍历二叉树
  2. 建立数组view保存最后结果,建立队列q保存<节点指针,高度>这样绑定的数据(可以稍微看一下pair的用法,不难,很好理解)
  3. 以根节点的高度为0开始,当数组的size()和高度相同时,此时我们需要把节点添加进数组中。当两者不相同时,此时我们需要更新以高度为下标的数组的值,来保证,view里存储的都是各个层最右边的节点。
  4. 最终view存储的就是各个层最右边的节点,返回即可。

以图示二叉树举例说明:

view[0] = 1

view[1] = 2

接下来遍历到5节点,这时高度还是1,但数组的size()为2,二者并不相同了,所以要更新view数组,来保证存储的是最右边的节点。

view[1] = 5

接下来遍历3节点,此时高度为2,view的size()也是2,所以向数组插入数据

view[2] = 3

接下来遍历的节点,高度和size又不再相同了,此时需要更新view保证是最右边的节点,以此类推。

主要思路是层次遍历的思路+对关键节点的判断

四 完整代码及注释

代码语言:javascript
复制
//
// Created by renyi on 2019-07-09.
//
#include <iostream>
#include <vector>
#include <queue>
using namespace std;

struct TreeNode{
    int value;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int v) : value(v), left(NULL), right(NULL) {}
};

vector<int> rightSideViewTree(TreeNode* root){
    vector<int> view;//建立数组view,保存二叉树的各层最右边的节点
    queue<pair<TreeNode*, int>> q;//建立队列q,保存<节点,层数>绑定在一起的数据

    if (root){//当根节点非空时,将<root, 0>push进入队列
        q.push(make_pair(root, 0));
    }

    while (!q.empty()){//当队列非空时,一直循环
        TreeNode* node = q.front().first;//取队头的第一个元素,第一次取,就是根节点指针root
        int depth = q.front().second;//取队头第二个元素,第一次取,就是根节点高度,就是0
        q.pop();

        if (view.size() == depth){//当view.size()=高度depth时,说明又往深遍历了一层,此时要往view中添加节点
            view.push_back(node->value);
        } else{//只要不相等,说明遍历的节点还在同一层,更新下标为depth的值,即更新更靠右的节点值
            view[depth] = node->value;
        }

        if (node->left){//层次遍历,将左右子树添加进队列,同时高度+1
            q.push(make_pair(node->left, depth+1));
        }
        if (node->right){
            q.push(make_pair(node->right, depth+1));
        }
    }
    return view;
}

int main(){
    TreeNode a(1);//建立配图的二叉树
    TreeNode b(2);
    TreeNode c(5);
    TreeNode d(3);
    TreeNode e(4);
    //TreeNode f(6);

    a.left = &b;
    a.right = &c;
    b.left = &d;
    b.right = &e;
    //c.right = &f;

    vector<int> result = rightSideViewTree(&a);
    for (int i = 0; i < result.size(); i++) {
        printf("[%d]", result[i]);
    }
    printf("\n");
    return 0;
}

代码中,是为了测试去掉节点6的运行结果

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-07-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 算法其实很好玩 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档