二叉树相关面试题目之实例总结

来源:互联网 发布:八卦九宫打法优化版 编辑:程序博客网 时间:2024/06/07 05:28

编码解决二叉树问题能够帮助我们深入理解递归思想,并能提高代码能力。在这里总结上一周实现的五个小例题,从《程序员代码面试指南》里面挑选出来的。它们是:二叉树的序列化和反序列化、找到二叉树中指定值的最长路径长度、找到二叉树中最大的二叉搜索子树、层序打印、搜索二叉树中两个错误的节点和判断二叉树r1是否包含二叉树r2的全部拓扑结构。

1、二叉树的序列化和反序列化

代码包含二叉树的先序序列化、先序反序列化,以及层序的序列化、层序的反序列化。下面是代码部分:

//先序序列化这棵树public static String serialByPre(Node root) {//递归实现二叉树的先序序列化    if (root == null) {        return "#!";    }    String res = root.data + "!";    res += serialByPre(root.left);    res += serialByPre(root.right);    return res;}public static Node reconByPreString(String str) {//字符串反序列化二叉树    String[] vals = str.split("!");    Queue<String> queue = new LinkedList<String>();    for (int i = 0; i < vals.length; i++) {        queue.offer(vals[i]);    }    return reconPreOrder(queue);}private static Node reconPreOrder(Queue<String> queue) {//对字符串队列,使用递归方法将其反序列化为二叉树    String value = queue.poll();    if (value.equals("#")) {        return null;    }    Node head = new Node(Integer.parseInt(value));    head.left = reconPreOrder(queue);    head.right = reconPreOrder(queue);    return head;}//层序序列化和反序列化public static String serialByLevel(Node root){    if(root == null){        return "#!";    }    Queue<Node> queue = new LinkedList<Node>();    String ret = root.data+"!";    queue.offer(root);    while(!queue.isEmpty()){        Node top = queue.poll();        if(top.left != null){            ret+=top.left.data+"!";            queue.offer(top.left);        }else{            ret+="#!";        }        if(top.right != null){            ret+=top.right.data+"!";            queue.offer(top.right);        }else{            ret+="#!";        }    }    return ret;}public static Node reconByLevelString(String str){    String[] items = str.split("!");    int index =0;    Queue<Node> queue = new LinkedList<Node>();//队列暂存Node    Node head = getNode(items[index++]);    queue.offer(head);    while(!queue.isEmpty()){        Node top = queue.poll();        top.left=getNode(items[index++]);        top.right=getNode(items[index++]);        if(top.left != null){            queue.offer(top.left);        }        if(top.right != null){            queue.offer(top.right);        }    }    return head;}private static Node getNode(String string) {    if(!string.equals("#")){        return new Node(Integer.parseInt(string));    }    return null;}

2、找到二叉树中指定值的最长路径长度

给定一个指定的路径长度,二叉树路径中跨越层数的最大值。

// 在二叉树中找到累加和为指定值的最长路径长度public static int getMaxLength(Node root,int sum){//root-根节点,sum-指定的值    HashMap<Integer,Integer> sumMap = new HashMap<Integer,Integer>();    sumMap.put(0, 0);//路径长度为0的最大路径长度为0    return preOrder(root,sum,0,1,0,sumMap);} private static int preOrder(Node root, int sum, int preSum, int level,     int maxLen, HashMap<Integer, Integer> sumMap) {//preSum-记录上次统计的值,level-二叉树层数,maxLen-最大路径长度,sumMap-中间变量保存队列    if(root == null){        return maxLen;    }    int curLen = preSum + root.data;    if(!sumMap.containsKey(curLen)){        sumMap.put(curLen, level);    }    if(sumMap.containsKey(curLen-sum)){        maxLen = Math.max(level-sumMap.get(curLen-sum), maxLen);    }    maxLen=preOrder(root.left,sum,curLen,level+1,maxLen,sumMap);    maxLen=preOrder(root.right,sum,curLen,level+1,maxLen,sumMap);    return maxLen;}

3、找到二叉树中最大的二叉搜索子树

在二叉树中找到最大的二叉搜索子树,并返回该二叉树搜索子树的头结点。

     // 找到二叉树中最大的搜索二叉子树    public static Node getMaxSub(Node root){        if(root == null){            return null;        }        int[] recorde = new int[3];        return posOrder(root,recorde);    }    private static Node posOrder(Node root, int[] recorde) {    /*    二叉树后序遍历解决问题。    recorde记录中间信息,0号位置记录节点个数,1号位置记录最小值,2号位置记录最大值。    */        if(root == null){            recorde[0]=0;            recorde[1]=Integer.MAX_VALUE;            recorde[2]=Integer.MIN_VALUE;            return null;        }        int data = root.data;        Node left = root.left;        Node right = root.right;        Node lBST = posOrder(left,recorde);        int lsize = recorde[0];        int lmin = recorde[1];        int lmax = recorde[2];        Node rBST = posOrder(right,recorde);        int rsize = recorde[0];        int rmin = recorde[1];        int rmax = recorde[2];        recorde[1]=Math.min(lmin,data);        recorde[2]=Math.max(rmax, data);        if(left == lBST && right ==rBST && data>lmax && data<rmin){            recorde[0]=lsize+rsize +1;            return root;        }        recorde[0]=Math.max(lsize, rsize);        return lsize >rsize?lBST:rBST;    }

4、层序打印

   //顺序层序打印   public static void printByLevel(Node root){        if(root == null){            System.out.println("#");        }        Queue<Node>  queue = new LinkedList<Node>();        queue.offer(root);        Node last = root;        Node nlast = root;        while(!queue.isEmpty()){            Node item = queue.poll();            System.out.print(item.data+" ");            if(item.left != null){                nlast = item.left;                queue.offer(item.left);            }            if(item.right != null){                nlast = item.right;                queue.offer(item.right);            }            if(item == last){                System.out.println();                last = nlast;            }        }    }    //ZigZag方式层序打印二叉树    public static void printByLevelZig(Node root){        if(root == null){            System.out.println("#");        }        Queue<Node>  queue = new LinkedList<Node>();        Queue<Integer>  tmp  = new LinkedList<Integer>();        queue.offer(root);        Node last = root;        Node nlast = root;        boolean flag = true;        while(!queue.isEmpty()){            Node item = queue.poll();            //System.out.print(item.data+" ");            tmp.offer(item.data);            if(item.left != null){                nlast = item.left;                queue.offer(item.left);            }            if(item.right != null){                nlast = item.right;                queue.offer(item.right);            }            if(item == last){                pirntQueue(tmp,flag);                flag = !flag;                last = nlast;            }        }    }    private static void pirntQueue(Queue<Integer> tmp,boolean flag) {        if(flag){            while(!tmp.isEmpty()){                System.out.print(tmp.poll()+" ");            }        }else{            Object[] arry = new Object[tmp.size()];            arry=tmp.toArray();            int length = arry.length;            for(int i=0; i<length;i++){                System.out.print((int)arry[length-1-i]+" ");            }            tmp.clear();        }        System.out.println();    }

5、搜索二叉树中两个错误的节点

    //调整搜索二叉树中两个错误的节点    public static Node[] getTwoErrNodes(Node root){    /*    中序遍历方式,找到局部逆序的两个位置,找到两个错误节点。    */        Node[] errs = new Node[2];        if(root == null){            return errs;        }        Stack<Node> stack = new Stack<Node>();        Node pre = null;        while(!stack.isEmpty() || root !=null){            if(root != null){                stack.push(root);                root = root.left;            }else{                root = stack.pop();                if(pre != null && pre.data > root.data){                    errs[0]=errs[0]==null?pre:errs[0];                    errs[1]=root;                }                pre=root;                root=root.right;            }        }        return errs;    } 

6、判断二叉树r1是否包含二叉树r2的全部拓扑结构

   //判断二叉树r1是否包含二叉树r2的全部拓扑结构         public static boolean contains(Node r1,Node r2){    /*    递归方式解决问题,将问题转化为父节点和子节点问题。然后,针对左子树和右子树去解决问题。    */        if(r1 != null)            return check(r1,r2)||contains(r1.left,r2)||contains(r1.right,r2);        else            return false;    }    private static boolean check(Node r1, Node r2) {        if(r2 == null){            return true;        }        if(r1 == null || r1.data != r2.data){            return false;        }        return check(r1.left,r2.left) && check(r1.right,r2.right);    }
0 0
原创粉丝点击