二叉樹筆試面試題

package com.niukeprocess.practiceofbtree;

import java.lang.reflect.Array;
import java.util.*;

public class DepthOfBTree {
    public static void main(String[] args) {

    }

    //1.遞歸求二叉樹的深度
    public static int maxTreeDepth(TreeNode root){
        if(root == null) return 0;
        int left=maxTreeDepth(root.left);
        int right=maxTreeDepth(root.right);
         return (left>right)?(left+1):(right+1);
    }
    //2.非遞歸求二叉樹的深度,藉助輔助數據結構隊列,廣度優先遍歷二叉樹
    public static int heigthOfTree(TreeNode root){
        if(root==null){
            return 0;
        }
        ArrayDeque<TreeNode> queue= new ArrayDeque<TreeNode>();
        int height =0;
        queue.add(root);
        while(!queue.isEmpty()){
            int size=queue.size();
            for(int i=0;i<size;i++){
                TreeNode node=queue.removeFirst();
                if(node.left!=null){
                    queue.add(node.left);
                }
                if(node.right!=null){
                    queue.add(node.right);
                }
            }
            height++;

        }
        return height;
    }

    //3.求二叉樹的最小深度

    public static int minDepthOfTree(TreeNode root){
        if(root == null) return 0;
        int left = minDepthOfTree(root.left);
        int right =minDepthOfTree(root.right);
        if(left ==0&& right>0) return right+1;
        else if(right==0 && left>0) return  left+1;
        else return (left<right)?(left+1):(right+1);
    }


    //4.求二叉樹中結點的個數
    public static int sumOfTree(TreeNode root){
        if(root ==null) return 0;
        int left=sumOfTree(root.left);
        int right=sumOfTree(root.right);
        return 1+left+right;
    }

    //5.求二叉樹中葉子節點的個數
    public static int numOfLeaf(TreeNode root ){
        if(root == null) return 0;
        int count=0;
        if(root.left==null && root.right==null) count++;
        numOfLeaf(root.right);
        numOfLeaf(root.left);
        return count;
    }

    //6.求二叉樹中第k層節點的個數
    public static int KLevelLeafNode(TreeNode root,int kLevel){
        if(root ==null || kLevel <=0) return 0;
        if(root != null && kLevel==1) return 1;
        return (KLevelLeafNode(root.left,kLevel-1)+KLevelLeafNode(root.right,kLevel-1));
    }

    //7.判斷二叉樹是否爲平衡二叉樹
    //平衡二叉樹就是左子樹和右子樹的高度差不能超過1,且左右子樹必須是平衡二叉樹,且左右子樹必須是平衡二叉樹
    public static boolean IsBalanced(TreeNode root){
        if(root == null) return true;
        if(Math.abs(maxTreeDepth(root.left)-maxTreeDepth(root.right))<=1){
            return (IsBalanced(root.left) && IsBalanced(root.right));
        }else{
            return false;
        }
    }


    //8.判斷二叉樹是否是完全二叉樹
    /**
     * 判斷一個樹是否屬於完全二叉樹可以從以下2個條件來判斷:
     *  層次遍歷二叉樹
     *  1.任何一個結點如果右孩子不爲空,左孩子卻是空,則一定不是完全二叉樹;
     *  2.當一個節點出現右孩子爲空時候,判斷該節點的層次遍歷後繼結點是否爲葉子
     *  節點,如果全部都是葉子節點,則是完全二叉樹,如果存在任何一個結點不是葉
     *  子結點,則一定不是完全二叉樹
     *
     *
     */


    public static boolean isCBT(TreeNode node){
        if(node ==null) return false;
        TreeNode leftChild=null;
        TreeNode rightChild=null;
        boolean left=false;//葉節點判斷標誌
        Queue<TreeNode> queue=new LinkedList<TreeNode>();
        queue.offer(node);
        while(!queue.isEmpty()){
            TreeNode head=queue.poll();
            leftChild=head.left;
            rightChild=head.right;

            //右孩子不等於空,左孩子等於空-->false
            if((rightChild!=null && leftChild==null) ||
                    //開啓葉節點判斷標誌位時,如果層次遍歷中的後繼結點不是葉節點-->false
                    (left && (rightChild!=null  || leftChild!=null))){
                return false;
            }
            if(leftChild != null){
                queue.offer(leftChild);
            }

            if(rightChild != null){
                queue.offer(rightChild);
            }else {
                left = true;
            }
        }

        return  true;
    }

    /**
     * 9.兩個二叉樹是否完全相同
     * 基本思想:如果兩棵樹都爲空則相同
     * 如果其中一顆數爲空,則不同
     * 如果兩棵誰都不爲空,則判斷左右子樹是否相同
     *
     */
    public static boolean IsSame(TreeNode first,TreeNode second){
        if(first == null && second == null) return true;
        else if(first ==null || second == null) return false;
        if(first != null && second !=null){
            if(first.data != second.data) return false;
            else return IsSame(first.left,second.left) && IsSame(first.right,second.right);
        }
        return false;
    }

    /**
     * 10.兩個二叉樹是否互爲鏡像(對稱)
     * 基本思想:
     * 首先判斷這棵樹是否爲空樹,如果空樹則直接返回true
     * 如果不爲空,則進行分類:
     *  case1:節點左右子樹爲空,則直接返回true
     *  case2;節點的左右子樹有一個爲空,則直接返回false
     *  case3:節點的左右子樹均不爲空,則判斷節點的左右子節點的值是否相等
     *          並且判斷左節點的子左節點和右節點的右子節點是否對稱
     *          還有左節點的右子節點和右節點的左子節點是否對稱
     */

    public static boolean IsSymmetry(TreeNode root){
        if(root == null) return true;
        return  IsSymmetry(root.left, root.right);
    }

    private static boolean IsSymmetry(TreeNode left, TreeNode right) {
        if(left == null && right == null ) return true;
        if(left == null  || right == null) return false;
        return left.data == right.data && IsSymmetry(left.left,right.right) && IsSymmetry(left.right,right.left);
    }

    /**
     *
     * 11.翻轉二叉樹或鏡像二叉樹
     *
     */

    public static TreeNode invertTree(TreeNode root){
        if(root == null) return null;
        TreeNode left = invertTree(root.left);
        TreeNode right = invertTree(root.right);

        root.left=right;
        root.right=left;
        return root;
    }

    /**
     * 12.求兩個二叉樹的最低公共祖先節點
     *
     */

    public static TreeNode findParent(TreeNode root,TreeNode node1,TreeNode node2) {
        if(findNode(root.left,node1)){
            if(findNode(root.right,node2)) return root;
            else return findParent(root.left,node1,node2);
        }else{
            if(findNode(root.left,node2)) return root;
            else return  findParent(root.right,node1,node2);
        }

    }

        public static boolean findNode(TreeNode root,TreeNode node){
            if(root == null || node == null) return false;
            if(root == node) return true;
            boolean found = findNode(root.left,node);
            if(!found) found=findNode(root.right,node);
            return found;

        }
    /**
     * 二叉樹的前序遍歷
     */

    //遞歸解法
    public static ArrayList<Integer> preOrderReverse(TreeNode root){
        ArrayList<Integer> result = new ArrayList<Integer>();
        preOrder2(root ,result);
        return result;
    }

    private static void preOrder2(TreeNode root, ArrayList<Integer> result) {
        if(root == null ) return;
        result.add((Integer) root.data);
        preOrder2(root.left,result);
        preOrder2(root.right,result);
    }
    //迭代解法
    public static ArrayList<Integer> preOrder(TreeNode root){
        Stack<TreeNode> stack =new Stack<TreeNode>();
        ArrayList<Integer> list=new ArrayList<Integer>();
        if(root == null) return list;
        stack.push(root);
        while(!stack.isEmpty()){
            TreeNode node=stack.pop();
            list.add((Integer) node.data);
            if(node.right!=null) stack.push(node.right);
            if(node.left !=null) stack.push(node.left);
        }
        return list;
    }

    //二叉樹的中序遍歷
    public static ArrayList<Integer> inOrder(TreeNode root){
        ArrayList<Integer> list= new ArrayList<Integer>();
        Stack<TreeNode> stack =new Stack<TreeNode>();
        TreeNode cur=root;
        while(cur!=null || !stack.isEmpty()){
            while(cur!=null){
                stack.add(cur);
                cur=cur.left;
            }
            cur=stack.peek();
            stack.pop();
            list.add((Integer) cur.data);
            cur=cur.right;
        }
        return list;
    }

    //二叉樹的後序遍歷
    public static ArrayList<Integer> postOrder(TreeNode root){
        ArrayList<Integer> list =new ArrayList<Integer>();
        if(root == null) return list;
        list.addAll(postOrder(root.left));
        list.addAll(postOrder(root.right));
        list.add((Integer) root.data);
        return list;
    }

    /**
     * 前序遍歷和後序遍歷構造二叉樹
     */

    /**
     * 輸入一個二叉樹和一個整數,打印出二叉樹中結點值的和等於輸入整數
     * 所有的路徑
     */

    public static  void findPath(TreeNode root,int i){
        if(root == null) return;
        Stack<Integer> stack =new Stack<Integer>();
        int currentSum=0;
        findPath(root,i,stack,currentSum);
    }

    private static void findPath(TreeNode root, int i, Stack<Integer> stack, int currentSum) {
        currentSum+=(Integer) root.data;
        stack.push((Integer)root.data);
        if(root.left == null && root.right==null){
            if(currentSum== i){
                for(int path:stack){
                    System.out.println(path);
                }
            }
        }
        if(root.left != null) findPath(root.left,i,stack,currentSum);
        if(root.right !=null) findPath(root.right,i,stack,currentSum);
        stack.pop();
    }

    /**
     * 二叉樹的層次遍歷
     */

    public static ArrayList<ArrayList<Integer>> levelOrder(TreeNode root){
        ArrayList<ArrayList<Integer>> result=new ArrayList<ArrayList<Integer>>();
        if(root == null) return result;
        Queue<TreeNode> queue=new LinkedList<TreeNode>();
        queue.offer(root);
        while(!queue.isEmpty()){
            int size=queue.size();
            ArrayList<Integer> level=new ArrayList<Integer>();
            for(int i=0;i<size;i++){
                TreeNode node=queue.poll();
                level.add((Integer) node.data);
                if(node.left !=null) queue.offer(node.left);
                if(node.right !=null) queue.offer(node.right);
            }
            result.add(level);
        }
        return result;
    }
}

 

發佈了81 篇原創文章 · 獲贊 16 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章