首页 > 其他分享 >洛谷题单指南-二叉树-P1185 绘制二叉树

洛谷题单指南-二叉树-P1185 绘制二叉树

时间:2024-03-19 11:55:55浏览次数:29  
标签:删除 int 洛谷题 depth del 二叉树 P1185 节点

原题链接:https://www.luogu.com.cn/problem/P1185

题意解读:在表格中绘制二叉树,有几个关键点

1、结点用小写字母 o 表示,对于一个父亲结点,用 / 连接左子树,用 \ 连接右子树,表格其余地方填空格。

2、第m 层结点若两个属于同一个父亲,那么它们之间由 3 个空格隔开;若两个结点相邻但不属于同一个父亲,那么它们之间由1个空格隔开,据此可以计算第m层的宽度。

解题思路:

1、初始化画布大小

用二维数组代表画布,初始全部都是空格

char graph[800][2000]; 

画布的高、宽如何确定,结合题意,观察图形:

m = 2时,

  o  
 / \ 
o   o

高度 = 3,宽度 = 5

m = 3时,

     o     
    / \    
   /   \   
  o     o  
 / \   / \ 
o   o o   o

高度 = 6, 宽度 = 5 * 2 + 2 - 1 (最底层一对节点宽度是5,一共有2对,2对之间有2 - 1个空格)

m = 4时,

           o           
          / \          
         /   \         
        /     \        
       /       \       
      /         \      
     o           o     
    / \         / \    
   /   \       /   \   
  o     o     o     o  
 / \   / \   / \   / \ 
o   o o   o o   o o   o

高度 = 12, 宽度 = 5 * 4 + 4 - 1最底层一对节点宽度是5,一共有4对,4对之间有4 - 1个空格)

根据上述分析,可以推出二叉树画布的高度 = 3 * 2 ^ (m - 2),宽度 = 5 * 2 ^ (m - 2) + 2 ^ (m - 2) - 1

2、递归画图

先计算二叉树的根节点位置,从根节点开始,递归画图

画图函数如下:

void draw(int x, int y, int depth, int i, int j)

x, y表示起始节点,depth表示起始节点到左右相连的树枝的高度,i,j表示该节点是第i层第j个:

接下来调用

 w = 5 * pow(2, m - 2) + pow(2, m - 2) - 1; //二叉树底部宽度
 h = 3 * pow(2, m - 2); //二叉树高度
 draw(1, w / 2 + 1, (h + 1) / 2, 1, 1); //根节点在第一行正中间

x = 1, y = w / 2 + 1表示第一行的正中间,是根节点所在位置

depth = (h + 1) / 2表示要画的x、y与其相连的树枝的总高度,如m = 4时,表示要画这样的图形:

           o           
          / \          
         /   \         
        /     \        
       /       \       
      /         \  

画完根节点以及与之相连的树枝,再计算左子结点的位置、右子节点的位置,递归画图。

3、删除节点

如何实现节点删除呢?

可以用二维数组保存删除的节点

bool del[20][600]; 

del[i][j] = true表示第i层第j个节点被删除

在上述draw函数中,已经记录了每个节点是第几层第几个,只需要再画(x、y)节点之后,判断左、右子节点是否被删除,如果被删除则树枝和相应递归就不再继续画,就实现了删除的功能。

100分代码:

 

#include <bits/stdc++.h>
using namespace std;

char graph[800][2000]; //画布
bool del[20][600]; //被删除的节点
int m, n, w, h;

//从root开始,画高度是depth的节点和树枝,节点是第i层第j个
void draw(int x, int y, int depth, int i, int j)
{
    //画节点
    graph[x][y] = 'o';
    if(i == m) return; //最后一层
    int ileft = i + 1, jleft = j * 2 - 1; //左子结点是第ilfet层、第jleft个
    int iright = i + 1, jright = j * 2; //右子节点是第iright层,第jright个
    //画树枝
    for(int i = 1; i < depth; i++)
    {
        if(!del[ileft][jleft]) graph[x + i][y - i] = '/'; //左边树枝,如果左子节点被删除,不画树枝
        if(!del[iright][jright]) graph[x + i][y + i] = '\\'; //右边,如果右子节点被删除,不画树枝
    }
    if(!del[ileft][jleft]) draw(x + depth, y - depth, (depth + 1) / 2, ileft, jleft); //如果左子节点未删除,递归画左子树
    if(!del[iright][jright]) draw(x + depth, y + depth, (depth + 1) / 2, iright, jright); //如果右子节点未删除,递归画右子树
}

void show()
{
    for(int i = 1; i <= h; i++)
    {
        for(int j = 1; j <= w; j++)
        {
            cout << graph[i][j];
        }
        cout << endl;
    }
}

int main()
{
    memset(graph, ' ', sizeof(graph));
    cin >> m >> n;
    int x, y;
    while(n--)
    {
        cin >> x >> y;
        del[x][y] = true;
    }
    w = 5 * pow(2, m - 2) + pow(2, m - 2) - 1; //二叉树底部宽度
    h = 3 * pow(2, m - 2); //二叉树高度
    draw(1, w / 2 + 1, (h + 1) / 2, 1, 1); //根节点在第一行正中间
    show();
    return 0;
}

 

标签:删除,int,洛谷题,depth,del,二叉树,P1185,节点
From: https://www.cnblogs.com/jcwy/p/18082454

相关文章

  • 第七节:二叉树的先序、中序、后续遍历的多种递归写法
    一.        二.        三.         !作       者:Yaopengfei(姚鹏飞)博客地址:http://www.cnblogs.com/yaopengfei/声     明1:如有错误,欢迎讨论,请勿谩骂^_^。声     明2:原创博客请在转载......
  • 代码随想录算法训练营第十四天| 二叉树相关
    二叉树的递归遍历递归三要素:确定递归函数的参数和返回值,确定终止条件,确定单层递归的逻辑144.二叉树的前序遍历https://leetcode.cn/problems/binary-tree-preorder-traversal/description/publicList<Integer>preorderTraversal(TreeNoderoot){List<Integer>......
  • 【算法与数据结构】二叉树链式结构的实现【前中后序】
    文章目录......
  • 对称二叉树
    这里考试的时候其实就是想考递归,但是我实在是不清楚为什么\(n\)能够开到\(100W\)。。。这不随便超时吗介绍一个确定性算法的判断一个二叉树是否对称首先一个二叉树的中序遍历有两种,一个是先遍历左子树,一个是先遍历右子树,我们用结构归纳法,可以证明以树根为中心翻转其中一种中序遍......
  • 数据结构入门——二叉树(中)
    通过《二叉树(上)》的学习,我们已经对二叉树有了基本的了解,那我们现在继续深入了解二叉树。二叉树的存储结构顺序存储顺序结构存储就是使用数组来存储,一般使用数组只适合表示完全二叉树,因为不是完全二叉树会有空间的浪费。而现实中使用中只有堆才会使用数组来存储,关于堆我们后......
  • 二叉树|二叉树理论基础、二叉树的递归遍历
    代码随想录(programmercarl.com)树和二叉树1.树的基本概念1.1树的定义1.2树的逻辑表示方法1.3树的基本术语1.4树的性质1.5树的基本运算1.6树的存储结构2.二叉树的概念和性质2.1二叉树的定义2.2二叉树的性质2.3二叉树与树、森林之间的转换3.二叉树的存储结构3.1......
  • 洛谷题单指南-二叉树-P3884 [JLOI2009] 二叉树问题
    原题链接:https://www.luogu.com.cn/problem/P3884题意解读:要计算二叉树的深度、宽度、节点间的距离,深度、宽度的概念很好理解,节点间的距离描述是:节点u,v之间的距离表示从u到v的最短有向路径上向根节点的边数的两倍加上向叶节点的边数。说人话就是:u到v的距离=uv最近公共祖先到u......
  • 二叉树的广度优先遍历(力扣102)
    文章目录题目前知BFS是什么?队列的基本操作有什么?题解一、思路二、解题方法三、Code总结题目Problem:102.二叉树的层序遍历给你二叉树的根节点root,返回其节点值的层序遍历。(即逐层地,从左到右访问所有节点)。前知BFS是什么?树的广度优先遍历(BFS)是一种遍......
  • 树与二叉树(数据结构)
    本篇博客讲解树与二叉树,后续会继续讲解堆——————————————————————1.树概念及结构1.1树的概念 树是一种非线性的数据结构,它是由n(n>=0)个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的......
  • Leecode 二叉树的前序遍历
    Day2刷题我的思路:用数组list存储遍历结果,利用ArrayList的方法实现嵌套!importjava.util.*;classSolution{//defininganarraylistpublicList<Integer>preorderTraversal(TreeNoderoot){List<Integer>Traversal=newArrayList<>();......