题目要求:

现在我们拥有全国的省、市、县、镇的行政信息,比如 浙江省 -> 杭州市 -> 西湖区 --> xx街道,请将这些信息构建成一棵树,根节点为全国,叶子节点为镇。

我的误解:

刚开始我并没有明白题意,走了弯路,只是简单的构建了一个多叉树。代码如下:

import java.util.ArrayList;
import java.util.List;

public class SiteTree {
    public final static String COUNTRY = "国";
    public final static String PROVINCE = "省";
    public final static String CITY = "市";

    private static class Node {
        private String level; //国》省》市》县》镇
        private String name; //例如:山东省、济南市等具体地名
        private List<Node> child; //下一级节点列表

        private Node(String level, String name) {
            this.level = level;
            this.name = name;
        }

        //Getter Setter
    }

    public static void main(String[] args) {
        //声明一个根节点
        Node GUO = new Node(SiteTree.COUNTRY, "中国");
        //山东省下的市级单位
        Node JINAN = new Node(SiteTree.CITY, "济南市");
        Node JINING = new Node(SiteTree.CITY, "济宁市");
        //将市级节点放入山东省级节点下
        Node QLU = new Node(SiteTree.PROVINCE, "山东省");
        SiteTree.add(QLU, JINAN, JINING);
        //将省级节点放入国级节点下
        Node ZJS = new Node(SiteTree.PROVINCE, "浙江省");
        SiteTree.add(GUO, QLU, ZJS);
        //不再举例...
        System.out.println(GUO);
    }

    public static void add(Node parent, Node... child) {
        List<Node> childs = new ArrayList<>();
        for (int i = 0; i < child.length; i++) {
            childs.add(child[i]);
        }
        parent.setChild(childs);
    }
}

当面试官看到代码后,提示我:你需要实现一个通用的方法。我没太明白,面试官又说:主要考察你对递归的使用。

看到这里,我忽然明白了面试官的意图:使用递归去构建N叉树

摆在我面前的一个问题是,我该如何去读取数据源,数据源储存的形式是什么?是文本文件还是数据库?

文本文件说实话,不太好实现,而且不规范,正常逻辑数据应该储存在数据库。

但是我现在总不能去装个数据库吧?再写DAO层查询接口?这不现实。

没办法,只能自己简单模拟下数据库操作了!

表结构都是一行一行的数据,那就用List。每行数据(节点)不能只有主键,还要有父节点的外键,因为题目要求也给出了数据是具有指向关系的 。

如何实现数据的查询呢?当然是用Stream,最简单。

分析到这里,完整的代码已经呼之欲出,请看大屏幕 ↘

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class SiteTree {
    public final static String COUNTRY = "国";
    public final static String PROVINCE = "省";
    public final static String CITY = "市";
    private static List<Node> list = initData();

    //结合数据库比较好实现,所以简单实现下!
    private static class Node{
        private int cid; //节点ID
        private int pid; //父节点ID
        private String level; //国》省》市》县》镇
        private String name; //例如:山东省、济南市等具体地名
        private List<Node> child = new ArrayList<>(); //下一级节点列表

        public Node(int cid, int pid, String level, String name) {
            this.cid = cid;
            this.pid = pid;
            this.level = level;
            this.name = name;
        }

        public int getCid() {
            return cid;
        }

        public int getPid() {
            return pid;
        }

        public String getName() {
            return name;
        }

        public List<Node> getChild() {
            return child;
        }

        @Override
        public String toString() {
            return "Node{" +
                    "cid=" + cid +
                    ", pid=" + pid +
                    ", level='" + level + '\'' +
                    ", name='" + name + '\'' +
                    ", child=" + child +
                    '}';
        }
    }

    /**
     * 初始化数据库
     * @return
     */
    private static List<Node> initData() {
        //声明一个根节点
        Node GUO = new Node(1,0,SiteTree.COUNTRY,"中国");
        //将市级节点放入山东省级节点下
        Node QLU = new Node(4,1,SiteTree.PROVINCE, "山东省");
        //将省级节点放入国级节点下
        Node ZJS = new Node(5,1,SiteTree.PROVINCE,"浙江省");
        //山东省下的市级单位
        Node JINAN = new Node(2,4,SiteTree.CITY,"济南市");
        Node JINING = new Node(3,4,SiteTree.CITY,"济宁市");
        //简单数据库实现
        List<Node> list = new ArrayList<>();
        list.add(GUO);
        list.add(JINAN);
        list.add(JINING);
        list.add(QLU);
        list.add(ZJS);
        return list;
    }

    public static void main(String[] args){
        System.out.println(child(1));
    }

    private static Node child(int cid) {
        //获取节点
        Node node = getTreeNode(cid);
        //获取子节点
        List<Node> childNodes = getChildNode(cid);
        //遍历子节点
        for (Node child : childNodes){
            Node n = child(child.getCid());//递归
            node.getChild().add(n);
        }
        return node;
    }

    private static Node getTreeNode(int cid) {
        return list.stream().filter(node -> {
            if (node.getCid() == cid) {
                return true;
            }
            return false;
        }).findFirst().get();
    }

    private static List<Node> getChildNode(int pid) {
        return list.stream().filter(node -> {
            if (node.getPid() == pid) {
                return true;
            }
            return false;
        }).collect(Collectors.toList());
    }

}

打印输出:

Node{cid=1, pid=0, level='国', name='中国', child=[
Node{cid=4, pid=1, level='省', name='山东省', child=[
Node{cid=2, pid=4, level='市', name='济南市', child=[]},
Node{cid=3, pid=4, level='市', name='济宁市', child=[]}]},
Node{cid=5, pid=1, level='省', name='浙江省', child=[]}]}

这是我的解答,如果你有更好的解答,欢迎评论分享!

BAT面试题:请使用递归构建N叉树的更多相关文章

  1. java算法面试题:递归算法题2 第1个人10,第2个比第1个人大2岁,依次递推,请用递归方式计算出第8个人多大?

    package com.swift; public class Digui_Return { public static void main(String[] args) { /* * 递归算法题2 ...

  2. 笔记 BAT 面试题 及部分答案

    题目出自:https://www.jianshu.com/p/c70989bd5f29本文出自 AWeiLoveAndroid的博客 2018年2月20日星期二 随笔 笔记 BAT 面试题 一.jav ...

  3. 猫哥网络编程系列:详解 BAT 面试题

    从产品上线前的接口开发和调试,到上线后的 bug 定位.性能优化,网络编程知识贯穿着一个互联网产品的整个生命周期.不论你是前后端的开发岗位,还是 SQA.运维等其他技术岗位,掌握网络编程知识均是岗位的 ...

  4. c++ 之面试题(3)数组递归查找

    题目描述 1. 给定严格升序(没有相等元素)的数组a,元素个数为cnt, 查找num在数组中的位置序号(以0位起始). 如果没找到则返回: 比num小且最靠近的元素位置序号. 若所有元素均大于num则 ...

  5. 刷完500道BAT面试题,我能去面试大厂了吗?

    面试之前先刷几篇面经,或者做几道热门面试题,想必是大家很熟悉的一种复习方式了,就像我们当年经常做五年高考三年模拟一样.但是可不要把面试题和面经当成你的主要复习方式,它只是锦上添花,绝非雪中送炭! 壹面 ...

  6. 给1~3年iOS开发 经验朋友们的一些建议(附BAT面试题)

    前言 由于笔者是做 iOS 开发的,因此本文也仅对做 iOS 的同行们有针对性,其他方向仅供参考. 1,如果你: 1~3年左右工作经验,本科,非计算机相关科班出生,学校又比较一般. 实习企业不理想没有 ...

  7. 最强Java并发编程详解:知识点梳理,BAT面试题等

    本文原创更多内容可以参考: Java 全栈知识体系.如需转载请说明原处. 知识体系系统性梳理 Java 并发之基础 A. Java进阶 - Java 并发之基础:首先全局的了解并发的知识体系,同时了解 ...

  8. BAT笔试试题常见试题总结含答案(持续更新。。。)

    (1)试题例如以下: class A { int a; short b; int c; char d; }; class B { double a; short b; int c; char d; } ...

  9. 【BAT面试题系列】面试官:你了解乐观锁和悲观锁吗?

    前言 乐观锁和悲观锁问题,是出现频率比较高的面试题.本文将由浅入深,逐步介绍它们的基本概念.实现方式(含实例).适用场景,以及可能遇到的面试官追问,希望能够帮助你打动面试官. 目录 一.基本概念 二. ...

随机推荐

  1. Java基础重要知识点-反射

    反射,如何把.java文件转化为.class文件 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信 ...

  2. Java Spring MVC框架搭建(一)

    环境准备 >>>>>>java JDK和tomcat,eclipse 1.创建项目 2.项目名称自定义,这边为demo 3.我们已经创建完一个动态网站的项目,还得下 ...

  3. AntZipUtils【基于Ant的Zip压缩解压缩工具类】

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 Android 压缩解压zip文件一般分为两种方式: 基于JDK的Zip压缩工具类 该版本存在问题:压缩时如果目录或文件名含有中文, ...

  4. 《HelloGitHub》第 30 期

    公告 截止到第 30 期,贡献者 终于到达 3 位数-- 100 位.谢谢各位的支持和贡献,想要加入的小伙伴,快来推荐项目吧! <HelloGitHub>第 30 期 兴趣是最好的老师,H ...

  5. Asp.Net Core中服务的生命周期选项区别和用法

    在做一个小的Demo中,在一个界面上两次调用视图组件,并且在视图组件中都调用了数据库查询,结果发现,一直报错,将两个视图组件的调用分离,单独进行,却又是正常的,寻找一番,发现是配置依赖注入服务时,对于 ...

  6. 一个用来爬小说的简单的Node.js爬虫

    小说就准备点天下霸唱和南派三叔的系列,本人喜欢看,而且数据也好爬.貌似因为树大招风的原因,这两作者的的书被盗版的很多,乱改的也多.然后作者就直接在网上开放免费阅读了,还提供了官网,猜想作者应该是允许爬 ...

  7. Linux网络技术管理及进程管理(week2_day4)--技术流ken

    OSI七层模型和TCP/IP四层模型 OSI七层模型:OSI(Open System Interconnection)开放系统互连参考模型是国际标准化组织(ISO)制定的一个用于计算机或通信系统间互联 ...

  8. 从一个点子到一个社区APP,是如何通过.NET实现的?——“文林物业系统”APP介绍及采访记录

    “文林物业系统”(简称“文林社区”)是一款与物业管理软件无缝衔接的移动端系统.可在线查看通知公告.报修.投诉建议.查询物业管理费.水电气等其他费用,并且支持在线缴费.以物业管理为接入点,在未来,将会致 ...

  9. 【Oracle学习笔记】索引

    1 简介 1)索引是数据库对象之一,用于加快数据的检索,类似于书籍的索引.在数据库中索引可以减少数据库程序查询结果时需要读取的数据量,类似于在书籍中我们利用索引可以不用翻阅整本书即可找到想要的信息. ...

  10. 用JS在html页面实现打印功能

    首先在head里面加入下面一段js代码: <script language="javascript"> function preview(oper) { if (ope ...