算法: 二叉树算法题

题目 :给出一列格式如数据,数据格式如下所示:

{"(1,2)", "(2,4)", "(5,7)", "(7,2)", "(9,5)"}

其中,对于数组内的一个元素,与二叉树的某一节点的对应关系是: 1i是一个二叉树结果的子结果,2i是其父节点,目前有任务,要求在创建二叉树前或创建过程中对数组做校验,判断数组是否可组成一个合格的二叉树。二叉树的条件是:

  • 只能有1个根节点;
  • 一个子节点有且只能有 1父节点;
  • 一个父节点 <=2个子节点;
核心代码(含调试过程中的一些信息):
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
public class BinaryTreeIncludeSample {

        public static void main(String[] args) {
//            List<Sample> listSample = Sample.getSampleList();
//            for (Sample sample : listSample) {
                System.out.println("");
                String result = start(args);
                if (result.equals("true")){
                    System.out.println("true");
                }else{
                    System.out.println("false");
                }
            //}
        }

    public static String start(String[] strArr)  {
        StringBuffer debugInfo = new StringBuffer("");
        Map<Integer, TreeNode> parents = new ConcurrentHashMap<>();
        Map<Integer, TreeNode> childs = new ConcurrentHashMap<>();
        if (strArr==null || strArr.length==0){
            return "";
        }
        for(String str:strArr){
            String[] ary = str.split(",");
            if (ary.length!=2){
                return "false";
            }

            if (ary[0].startsWith("(")){
                ary[0] = ary[0].substring(1);
            }
            if (ary[1].endsWith(")")){
                ary[1] = ary[1].substring(0,ary[1].length()-1);
            }

            int c = Integer.parseInt(ary[0]);
            int p = Integer.parseInt(ary[1]);


            if (!parents.containsKey(p)){
                parents.put (p,new TreeNode(p));
            }
            if (parents.get(p).left==null){
                parents.get(p).left = new TreeNode(c);
            }else if (parents.get(p).right==null){
                parents.get(p).right = new TreeNode(c);
            }else{
                // debugInfo.append(p+"有超过2个子节点").toString();
                //System.out.println(str.toString());
                return "false";
            }

            if (!childs.containsKey(c)){
                childs.put(c,new TreeNode(p,c));
            }else if (childs.get(c).left.value != c){
                //debugInfo.append(c + "有>1个父节点");
                return "false";
            }
        }


        Integer rootIndex = Arrays.asList(parents.keySet().toArray(new Integer[]{})).get(0);
        TreeNode rootNode = parents.get(rootIndex);
        parents.remove(rootIndex);
        childs.remove(rootNode.left.value);

        //构建binary tree
        AtomicInteger count = new AtomicInteger(parents.size()*4);
        createTreeNode(rootNode,rootNode,parents,childs,count);

        if (parents.size()>0) {
//            List<TreeNode> treeNodeList = new CopyOnWriteArrayList<>();
//            inorderTraversal(rootNode,treeNodeList);
//            List<Integer> treeValues =  treeNodeList.stream().map(item->{return item.value;}).collect(Collectors.toList());
//            List<String> list = parents.keySet().stream().map(p->{return "("+parents.get(p).left.value+","+ p +")";}).collect(Collectors.toList());
//            debugInfo.append("--BinaryTree:"+treeValues.toString());
//            debugInfo.append("--异常多出节点:"+list.toString());
//            System.out.println(debugInfo.toString());
            return "false";
        }else{
            return "true";
        }
    }


    public static TreeNode createTreeNode(TreeNode rootNode, TreeNode treeNode, Map<Integer, TreeNode> parents, Map<Integer, TreeNode> childs, AtomicInteger count){
        if (count.get()==0){
            return rootNode;
        }
        if (rootNode!=null && childs!=null && childs.containsKey(rootNode.value)){
            TreeNode node = childs.get(rootNode.value);
            node.left = rootNode;
            rootNode = node;
            parents.remove(node.value);
            childs.remove(node.left.value);
            count.decrementAndGet();
            return createTreeNode(rootNode,treeNode,parents,childs,count);
        }

        if (treeNode!=null && treeNode.left!=null && parents!=null && parents.containsKey(treeNode.left.value)){
            treeNode.left = parents.get(treeNode.left.value);
            parents.remove(treeNode.left.value);
            count.decrementAndGet();
            return createTreeNode(rootNode,treeNode.left,parents,childs,count);
        }

        if (treeNode!=null && treeNode.right!=null && parents!=null && parents.size()>0 && parents.containsKey(treeNode.right.value)){
            treeNode.right = parents.get(treeNode.right.value);
            parents.remove(treeNode.right.value);
            count.decrementAndGet();
            return createTreeNode(rootNode,treeNode.right,parents,childs,count);
        }

        return rootNode;
    }
}
二叉树类
 public static class TreeNode{
        final private int value;
        private TreeNode left;
        private TreeNode right;


        public TreeNode(int i){
            this.value = i;
        }

        public TreeNode(int i,int leftValue){
            this.value = i;
            this.left = new TreeNode(leftValue);
        }

        public String getParentLeft(){
            return "("+ left.value +","+ value +")";
        }
    }
样本数据类
public static class Sample{
        String[] strAry;
        boolean result;
        public Sample(String[] strAry,boolean result){
            this.strAry = strAry;
            this.result = result;
        }

        public static List<Sample> getSampleList(){
            List<Sample> strArrList = new LinkedList(Arrays.asList(new BinaryTree.Sample[]{
                    new BinaryTree.Sample(new String[]{"(1,2)", "(2,4)", "(5,7)", "(7,2)", "(9,5)"},true),
                    new BinaryTree.Sample(new String[] {"(1,2)", "(3,2)", "(2,12)", "(5,2)"},false),
                    new BinaryTree.Sample(new String[]{"(1,2)", "(2,4)", "(5,7)", "(7,2)", "(9,5)"},true),
                    new BinaryTree.Sample(new String[]{"(1,2)", "(2,4)", "(7,2)"},true),
                    new BinaryTree.Sample(new String[]{"(1,2)", "(1,2)"},true),
                    new BinaryTree.Sample(new String[]{},true),
                    new BinaryTree.Sample(new String[]{"(1,2)", "(1,3)"},false),
                    new BinaryTree.Sample(new String[]{"(1,2)", "(2,4)", "(7,2)", "(8,8)"},false),
                    new BinaryTree.Sample(new String[]{"(1,2)", "(4,2)", "(7,2)"},false),
                    new BinaryTree.Sample(new String[]{"(1,2)", "(4,2)", "(7,9)"},false),
            }));
            return strArrList;
        }
    }

另外一个样本创建方法
    public static TreeNode createTree(int rootIndex, List<Integer> list) {
        if (rootIndex >= list.size()) {
            return null;
        }
        TreeNode rootNode = new TreeNode(list.get(rootIndex));
        rootNode.left=createTree( 2 * rootIndex + 1, list);
        rootNode.right=createTree(2 * rootIndex + 2, list);

        return rootNode;
    }

判断二叉树是否相等
   public boolean isSamTree(TreeNode m,TreeNode n){
        if(m == null && n == null){
            return true;
        }
        if(m == null ^ n == null){
            return false;
        }
        return  (m.value == n.value && isSamTree(m.left,n.left) && isSamTree(m.right,n.right));
    }
二叉树的遍历(调试时会用上)
  /**
     * 前序遍历
     * @param root
     * @param ret
     * @return
     */
    public static List<TreeNode>  preorderTraversal(TreeNode root, List<TreeNode> ret){
        if(root == null)  return ret;

        if (ret==null){
           ret = new LinkedList<>();
        }
        ret.add(root);
        preorderTraversal(root.left,ret);
        preorderTraversal(root.right,ret);
        return ret;
    }


    /**
     * 中序遍历
     * @param root
     * @return
     */
    public static List<TreeNode> inorderTraversal(TreeNode root, List<TreeNode> list) {
        if(root == null)  return null;

        if (list==null){
            list = new LinkedList<>();
        }

        inorderTraversal(root.left,list);
        list.add(root);
        inorderTraversal(root.right,list);
        return list;
    }

    /**
     * 后序遍历
     * @param root
     * @param ret
     * @return
     */
    public static List<TreeNode> postorderTraversal(TreeNode root, List<TreeNode> ret) {
        if(root == null)  return ret;

        if (ret==null){
            ret = new LinkedList<>();
        }

        postorderTraversal(root.left,ret);
        ret.add(root);
        postorderTraversal(root.right,ret);
        return ret;
    }

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,463评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,868评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,213评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,666评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,759评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,725评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,716评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,484评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,928评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,233评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,393评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,073评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,718评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,308评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,538评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,338评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,260评论 2 352

推荐阅读更多精彩内容