0
点赞
收藏
分享

微信扫一扫

二叉树习题详解

快乐小鱼儿_9911 2022-02-18 阅读 22
java

目录

1.检验两棵树是否是相同的树

2.判断一棵树是否是另一棵树的子树

3.判断一棵树是否是平衡二叉树.

 4.对称二叉树

5.1层序遍历

5.2层序遍历返回每一层的节点

6.1二叉树的最近公共祖先

6.2求最近公共祖先方法2求链表的交点:

7.输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表

8.通过前序遍历和中序遍历构建二叉树

 9.通过后序遍历和中序遍历构建二叉树

10.二叉树的构建和遍历

11.非递归实现前序遍历

12.非递归实现中序遍历

13.非递归实现后序遍历


1.检验两棵树是否是相同的树

public boolean isSameTree(TreeNode p,TreeNode q){
        if((p == null && q != null) || (p != null && q == null)){
            return false;
        }
        if(p == null && q == null){
            return true;
        }
        if(p.val != q.val){
            return false;
        }
        return isSameTree(p.left,q.left) && isSameTree(p.right,q.right);
    }

2.判断一棵树是否是另一棵树的子树

 public boolean isSameTree(TreeNode p, TreeNode q) {
        if ((p == null && q != null) || (p != null && q == null)) {
            return false;
        }
        if (p == null && q == null) {
            return true;
        }
        if (p.val != q.val) {
            return false;
        }
        return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
    }

    public boolean isSubTree(TreeNode root, TreeNode subRoot) {
        if (root == null || subRoot == null) {
            return false;
        }
        if (isSameTree(root, subRoot)) {
            return true;
        }
        if (isSameTree(root.left, subRoot)) {
            return true;
        }
        if (isSameTree(root.right, subRoot)) {
            return true;
        }
        return false;
    }

3.判断一棵树是否是平衡二叉树.

public int height(TreeNode root){
        if(root == null){
            return 0;
        }
        int leftHeight = height(root.left);
        int rightHeight = height(root.right);
        if(leftHeight >=0 && rightHeight >=0 && Math.abs(leftHeight-rightHeight) <= 1){
            return Math.max(leftHeight,rightHeight)+1;
        }else{
            return -1;
        }
    }
    public boolean isBalanced(TreeNode root){
      if(root == null){
          return true;
      }
      return height(root) > 0;
    }

 4.对称二叉树

public boolean isSymmetricChild(TreeNode leftTree,TreeNode rightTree){
        if((leftTree == null && rightTree != null)||(leftTree != null && rightTree == null)){
            return false;
       }
        //空节点也是对称
        if(leftTree == null && rightTree == null){
            return true;
        }
        
        if(leftTree.val != rightTree.val){
            return false;
        }
        return isSymmetricChild(leftTree.left,rightTree.right) && isSymmetricChild(leftTree.right,rightTree.left);
   }
   //对称二叉树
   public boolean isSymmetric(TreeNode root){
        if(root == null){
            return true;
        }
        return isSymmetricChild(root.left,root.right);
   }

5.1层序遍历

public void levelOrder1(TreeNode root){
            Queue<TreeNode> queue = new LinkedList<>();
            if(root == null){
                return;
            }
            queue.offer(root);
            while (! queue.isEmpty()){
                TreeNode cur = queue.poll();
                System.out.println(cur.val+" ");
                if(cur.left != null){
                    queue.offer(cur.left);
                }
                if(cur.right != null){
                    queue.offer(cur.right);
                }
            }
    }

5.2层序遍历返回每一层的节点

 public List<List<Integer>> levelOrder2(TreeNode root){
       List<List<Integer>> ret = new ArrayList<>();
       Queue<TreeNode> queue = new LinkedList<>();
       if(root == null){
           return ret;
       }
       queue.offer(root);
       while (! queue.isEmpty()){
          int size = queue.size();
          List<Integer> list = new ArrayList<>();
          while (size != 0){
              TreeNode cur = queue.poll();
              list.add(cur.val);
              if(cur.left != null){
                  queue.offer(cur.left);
              }
              if(cur.right != null){
                  queue.offer(cur.right);
              }
              size--;
          }
          ret.add(list);、//每层的节点走完之后放在list中
       }
       return ret;
   }

6.1二叉树的最近公共祖先

方法一:

 

 //找公共祖先方法1之将其看成二叉搜索树
    public TreeNode lowestCommonAncestor1(TreeNode root,TreeNode p,TreeNode q){
        if(root == null){
            return null;
        }
        if(root == p || root == q){
            return root;
        }
        TreeNode leftT = lowestCommonAncestor1(root.left,p,q);
        TreeNode rightT = lowestCommonAncestor1(root.right,p,q);
         if(leftT != null && rightT != null){
             return root;
         }else if(leftT != null){
             return leftT;
         }else {
             return rightT;
         }
    }

6.2求最近公共祖先方法2求链表的交点:

//root: 根节点   node:指定的节点    stack:存放从根节点到指定节点的路径
    public boolean getPath(TreeNode root,TreeNode node,Stack<TreeNode> stack){
       if(root == null || node == null){
           return false;
       }
       stack.push(root);
       if(root == node){
           return true;
       }
       boolean flg = getPath(root.left,node,stack);
       if(flg == true){
           return true;
       }
       flg = getPath(root.right,node,stack);
       if(flg == true){
           return true;
       }
       stack.pop();
       return false;
    }
    public TreeNode lowestCommonAncestor2(TreeNode root,TreeNode p,TreeNode q){
      if(root == null){
          return null;
      }
        Stack<TreeNode> stack1 = new Stack<>();
        getPath(root,p,stack1);
        Stack<TreeNode> stack2 = new Stack<>();
        getPath(root,p,stack2);
        int size1 = stack1.size();
        int size2 = stack2.size();
        if(size1 > size2){
            int size = size1 - size2;
            while (size != 0){
                stack1.pop();
                size--;
            }
            while (!stack1.isEmpty() && !stack2.isEmpty()){
                //判断两个的地址
                if(stack1.peek() == stack2.peek()){
                   return stack1.pop();
                }else {
                    stack1.pop();
                    stack2.pop();
                }
            }
        }else{
            int size = size2 - size1;
            while (size != 0){
                stack2.pop();
                size--;
            }
            while (!stack1.isEmpty() && !stack2.isEmpty()){
                //判断两个的地址是否相同
                if(stack1.peek() == stack2.peek()){
                    return stack1.pop();
                }else {
                    stack1.pop();
                    stack2.pop();
                }
            }
        }
        return null;
    }

7.输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表

 

 

 

 //输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表
    //中序遍历
    TreeNode prev = null;
    public void inorder(TreeNode pCur){
        if(pCur == null){
            return;
        }
        inOrder(pCur.left);
        pCur.left = prev;
        if(prev != null){
            prev.right = pCur;
        }
        prev = pCur;

        //打印
        //System.out.println(pCur.val+" ");
        inorder(pCur.right);
    }
    public TreeNode Convert(TreeNode pRootOfTree){
      if(pRootOfTree == null){
          return null;
      }
      inorder(pRootOfTree);
      TreeNode head = pRootOfTree;
      while (head.left != null){
          head = head.left;
      }
      return head;
    }

8.通过前序遍历和中序遍历构建二叉树

注意:下面的preIndex应该写在外面,防止循环结束,回去之后记不住当前位置

//通过前序遍历和中序遍历构建二叉树
    public int preIndex = 0;
    public TreeNode createTreeByPandI(int[] preorder,int[] inorder,int inbegin,int inend ){
     //递归终止条件,如果满足这个条件,说明没有左树或者右树了
        if(inbegin > inend){
         return null;
     }
      TreeNode root = new TreeNode(preorder[preIndex]);//构建前序遍历第一个节点
      int rootIndex = findIndexOfI(inorder,inbegin,inend,preorder[preIndex]);//在中序遍历中查找根节点的位置
       if(rootIndex == -1){
           return null;
       }
       preIndex++;
       root.left = createTreeByPandI(preorder,inorder,inbegin,rootIndex-1);
       root.right = createTreeByPandI(preorder,inorder,rootIndex+1,inend);
       return root;
    }
    private int findIndexOfI(int[] inorder,int inbegin,int inend,int key){
        for (int i = inbegin; i <=inend ; i++) {
          if(inorder[i] == key){
              return i;
          }
        }
        return -1;
    }
    public TreeNode buildTree(int[] preorder,int[] inorder){
       if(preorder == null || inorder == null){
           return null;
       }
       return createTreeByPandI(preorder,inorder,0,inorder.length-1);
    }

 9.通过后序遍历和中序遍历构建二叉树

和上面的类似,只需要简单修改即可:

//根据后序遍历和中序遍历构建二叉树

    public int postIndex = 0;

    public TreeNode createTreeByPandI(int[] inorder, int[] postorder,int inbegin,int inend){
        if(inbegin > inend){
            return null;
        }
        //在前序遍历中定义第一个节点
        TreeNode root = new TreeNode(postorder[postIndex]);
        //在中序遍历中找到根节点的位置
        int rootIndex = findIndex(inorder,inbegin,inend,postorder[postIndex]);
        if(rootIndex == -1){
            return null;
        }
        postIndex--;
        //先遍历右边,再遍历左边
        root.right = createTreeByPandI(inorder,postorder,rootIndex+1,inend);
        root.left = createTreeByPandI(inorder,postorder,inbegin,rootIndex-1);
        return root;
    }
    public int findIndex(int[] inorder,int begin,int inend,int key){
        for(int i = begin;i <= inend;i++){
            if(inorder[i] == key){
                return i;
            }
        }
        return -1;
    }
    public TreeNode buildTree(int[] postorder, int[] inorder) {
        if(postorder == null || inorder == null){
            return null;
        }
        postIndex = inorder.length-1;
        return createTreeByPandI(postorder,inorder,0,inorder.length-1);
    }
}

10.二叉树的构建和遍历

import java.util.*;
//构建节点
 class TreeNode{
   public char val;
   public TreeNode left;
   public TreeNode right;
   public TreeNode(char val){
      this.val = val;
  }
}
public class Main{
   public static int i =0;
    public static TreeNode createNode(String str){
        //新建一个根节点root,因为每次回来都要重新建一个新的节点。因此让其为空
        TreeNode root = null;
        if(str.charAt(i) != '#'){
            root = new TreeNode(str.charAt(i));
            i++;
            root.left = createNode(str);
            root.right = createNode(str);
           }else{
            i++;
        }
        return root;
    }
    //中序遍历
    public static void inOrder(TreeNode root){
        if(root == null){
            return;
        }
        
        inOrder(root.left);
        System.out.print(root.val+" ");
        inOrder(root.right);
    }
    public static void main(String[] arg){
        
        Scanner in = new Scanner(System.in);
       //hasNextLine遇到空格不结束
        //hasNext遇到空格就结束
        while(in.hasNextLine()){
            String str = in.nextLine();
            TreeNode root = createNode(str);
            inOrder(root);
        }
    } 

}

11.非递归实现前序遍历

void preOrderNor(TreeNode root) {
        Stack<TreeNode> stack = new Stack<>();
        TreeNode cur = root;
        while (cur != null || !stack.isEmpty()) {
            while (cur != null) {
                stack.push(cur);
                System.out.print(cur.val + " ");
                cur = cur.left;
            }

            TreeNode top = stack.pop();
            cur = top.right;
        }
    }

12.非递归实现中序遍历

 void inOrderNor(TreeNode root) {
        Stack<TreeNode> stack = new Stack<>();
        TreeNode cur = root;
        while (cur != null || !stack.isEmpty()) {
            while (cur != null) {
                stack.push(cur);
                cur = cur.left;
            }
            TreeNode top = stack.pop();
            System.out.print(top.val+" ");
            cur = top.right;
        }
    }

13.非递归实现后序遍历

public List<Integer> postorderTraversal(TreeNode root) {
       List<Integer> ret = new ArrayList();
       Stack<TreeNode> stack = new Stack<>();
       TreeNode cur = root;
       TreeNode prev = null;
        while(cur != null || !stack.isEmpty()){
            while(cur != null){
                stack.push(cur);
                cur = cur.left;
            }
            TreeNode top = stack.peek();
            if(top.right == null || top.right == prev){
              stack.pop();
              ret.add(top.val);
              prev = top;//指向弹出过的节点
            }else{
                cur = top.right;
            }
        }
        return ret;
    }

 

举报

相关推荐

0 条评论