蓝桥杯:二叉树垂直遍历

题目3 : 二叉树垂直遍历
时间限制:1000ms
单点时限:1000ms
内存限制:256MB

描述

对于一个二叉树,输出它的垂直遍历结果;对于同一列的节点,按照从左向右,从上向下的顺序排列。

特殊要求:请使用以下数据结构

class Node
{
int data;
Node left;
Node right
}

例如,对于以下二叉树:

  1
 / \
2   3
   /
  4

垂直遍历的结果是:2 1 4 3
输入

输入包含多组数据。对于每组数据:

第一行是n,表示节点个数(节点编号从0到n-1);当n=-1时,表示输入结束。(1 <= n <= 10)

之后的n行,每一行有三个整数,分别表示:节点的数值,左子树的编号,右子树的编号(编号-1表示节点为空)。
输出

针对每组输入,输出垂直遍历的结果。
样例输入

4
1 1 2
2 -1 -1
3 3 -1
4 -1 -1
-1

样例输出

2 1 4 3

思路:

先对二叉树进行层序遍历,并保存列数,对列数进行排序。

import java.util.*;

class Node {//题目规定用的结构
    int data;
    Node left;
    Node right;
}

class Map {//入队时用的结构,应为要记录他的列,父节点为0,左子树减一,右子树加一。
    int i;
    Node node;
}

public class test {
    static Queue<Map> queue = new LinkedList<>();//队列

    static Node test1(int[][] n, int k) {//用输入的数据建立树
        Node tree1 = new Node();
        tree1.data = n[k][0];
        if (n[k][1] == -1) {
            tree1.left = null;
        } else if (n[k][1] != -1) {
            tree1.left = test1(n, n[k][1]);
        }
        if (n[k][2] == -1) {
            tree1.right = null;
        } else if (n[k][2] != -1) {
            tree1.right = test1(n, n[k][2]);
        }
        return tree1;
    }

    public static void main(String[] args) {
        List<List<Integer>> lists = new ArrayList<>();
        Scanner in = new Scanner(System.in);
        int N ;
        while (true) {//有多组数据所以要循环
            java.util.Map<Integer, List<Integer>> mapput = new TreeMap<>();
           N = in.nextInt();
            List<Integer> list123 = new ArrayList<>();
            if (N == -1) {//当N为-1时,跳出循环,输出结果
                break;
            }
            int[][] n = new int[N][3];
            for (int i = 0; i < N; i++) {
                for (int j = 0; j < 3; j++) {
                    n[i][j] = in.nextInt();
                }
            }
            Node tree = test1(n, 0);//父节点
            Map map = new Map();
            map.i = 0;
            map.node = tree;
            queue.add(map);//父节点入队列
            while (queue.size()!=0) {//队列中所有节点都出来了,结束循环。
                map = queue.poll();//出队
                int i = map.i;//保存当前这棵树的父节点的列数
                tree = map.node;
                List<Integer> list = new ArrayList<>();
                if (mapput.containsKey(i)) {//查看map里是否已经存在这一列的数据,如果没有直接保存list如果有取出list,在list里添加当前节点的数据,再把list保存回去。
                    list = mapput.get(i);
                    list.add(map.node.data);
                } else {
                    list.add(map.node.data);
                }
                mapput.put(i, list);
                if (tree.left != null) {//如果左节点不为空,把父节点的列数减一,入队列
                    map = new Map();
                    int j = i;
                    map.i = j - 1;
                    map.node = tree.left;
                    queue.add(map);
                }
                if (tree.right != null) {//如果右节点不为空,把父节点的列数加一,入队列
                    map = new Map();
                    int j = i;
                    map.i = j + 1;
                    map.node = tree.right;
                    queue.add(map);
                }
            }
            List<Integer> list1 = new ArrayList<>();//先把结果保存起来,所有测试用例输入好了,再输出。
            for (List<Integer> list : mapput.values()) {
               list1.addAll(list);
            }
            lists.add(list1);
        }
        for (List<Integer> li:lists) {//输出结果
            for (int j : li) {
                System.out.print(j+" ");
            }
            System.out.println();
        }



    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1、树状显示二叉树: 编写函数displaytree(二叉树的根指针,数据值宽度,屏幕的宽度)输出树的直观示意图。输出的二叉树垂直打印的,同层的节点在同一行上。 问题描述: 假设数据宽度datawidth=2,而屏幕宽度screenwidth为64=26,假设节点的输出位置用 (层号,须打印的空格数)来界定。 第0层:根在(0,32)处输出; 第1层:因为根节点缩进了32个空格,所以下一层的偏移量(offset)为32/2=16=screenwidth/22。即第一层的两个节点的位置为(1,32-offset),(1,32+offset)即(1,16),(1,48)。 第二层:第二层的偏移量offset为screenwidth/23。第二层的四个节点的位置分别是(2,16-offset),(2,16+offset),(2,48-offset),(2,48+offset)即(2,8),(2,24),(2,40),(2,56)。 …… 第i层:第i层的偏移量offset为screenwidth/2i+1。第i层的每个节点的位置是访问第i-1层其双亲节点时确定的。假设其双亲的位置为(i-1,parentpos)。若其第i层的节点是其左孩子,那末左孩子的位置是(i,parentpos-offset),右孩子的位置是(i,parentpos+offset)。 提示:利用二叉树的层次遍历算法实现。利用两个队列Q,QI。队列Q中存放节点信息,队列QI中存相应于队列Q中的节点的位置信息,包括层号和需要打印节点值时需要打印的空格数。当节点被加入到Q时,相应的打印信息被存到QI中。二叉树本身采用二叉链表存储。 2、完全二叉树判断 用一个二叉链表存储的二叉树,判断其是否是完全二叉树
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值