二叉树的经典例题—数据结构

发布于:2022-11-09 ⋅ 阅读:(6) ⋅ 点赞:(0) ⋅ 评论:(0)

1. 某二叉树共有 399 个结点,其中有 199 个度为 2 的结点,则该二叉树中的叶子结点数为(C )

A 不存在这样的二叉树
B 200
C 198
D 199

思路:叶子结点数 = 度为2的结点数+1

2.在具有 2n 个结点的完全二叉树中,叶子结点个数为(A)

A n
B n+1
C n-1
D n/2

思路:在完全二叉树中,偶数个结点的度为1的结点个数一定为1,二叉树的结点总数 = 叶子结点个数+度为1的结点个数+度为2的结点个数,叶子结点数 = 度为2的结点数+1;连理可得叶子结点的个数为n

3.一个具有767个节点的完全二叉树,其叶子节点个数为()

A 383
B 384
C 385
D 386

思路:在完全二叉树中,奇数个结点的度为1的结点个数一定为0,二叉树的结点总数 = 叶子结点个数+度为1的结点个数+度为2的结点个数,叶子结点数 = 度为2的结点数+1

4. 一棵完全二叉树的节点数为531个,那么这棵树的高度为( B)

A 11
B 10
C 8
D 12

思路:深度为k的二叉树的结点总数为2^k-1

5.某完全二叉树按层次输出(同一层从左到右)的序列为 ABCDEFGH 。该完全二叉树的前序序列为(A)

A: ABDHECFG
B: ABCDEFGH
C: HDBEAFCG
D: HDEBFGCA

在这里插入图片描述

思路:前序遍历:根左右

6.二叉树的先序遍历和中序遍历如下:先序遍历:EFHIGJK;中序遍历:HFIEJKG.则二叉树根结点为(A)

A: E
B: F
C: G
D: H

7.设一课二叉树的中序遍历序列:badce,后序遍历序列:bdeca,则二叉树前序遍历序列为(D)

A: adbce
B: decab
C: debac
D: abcde

在这里插入图片描述

8.某二叉树的后序遍历序列与中序遍历序列相同,均为 ABCDEF ,则按层次输出(同一层从左到右)的序列为(A)

A: FEDCBA
B: CBAFED
C: DEFCBA
D: ABCDEF

在这里插入图片描述

9.检查两颗树是否相同

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);
    }

10.另一颗树的子树

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(isSubtree(root.left,subRoot)){
            return true;
        }
        if(isSubtree(root.right,subRoot)){
            return true;
        }
        return false;
    }

11. 二叉树最大深度

public int maxDepth(TreeNode root) {
        if(root == null){
            return 0;
        }
        int highLeft = maxDepth(root.left);
        int highRight = maxDepth(root.right);
        return highLeft<highRight?highRight+1:highLeft+1;
    }

12.判断一颗二叉树是否是平衡二叉树

//该算法的时间复杂度为O(N^2)
    public int getHeight(TreeNode root){
        if (root == null){
            return 0;
        }
        int leftHigh = getHeight(root.left);
        int rightHigh = getHeight(root.right);
        return leftHigh > rightHigh ? leftHigh+1 : rightHigh+1;
    }
    public boolean isBalanced(TreeNode root) {
        if (root == null){
            return true;
        }
        int leftHigh = getHeight(root.left);
        int rightHigh = getHeight(root.right);
        int tmp = leftHigh - rightHigh;
        if(tmp < 0){
            tmp = rightHigh - leftHigh;
        }
        return tmp <= 1&&isBalanced(root.left)&&isBalanced(root.right);
    }
    //该算法的时间复杂度为O(N)
    public boolean isBalanced(TreeNode root) {
        return getHeight(root)>=0;
    }
    public int getHeight(TreeNode root){
        if(root == null){
            return 0;
        }
        int leftL = getHeight(root.left);
        int rightL = getHeight(root.right);
        if(leftL >= 0 && rightL >= 0 && Math.abs(leftL - rightL) <= 1){
            return Math.max(leftL,rightL)+1;
        }else{
            return -1;
        }
    }

13.对称二叉树

public boolean isSymmetric(TreeNode root) {
        if(root == null){
            return true;
        }
        return isSymmetricChild(root.left,root.right);
    }
    public boolean isSymmetricChild(TreeNode rootLeft,TreeNode rootRight){
        if(rootLeft == null&&rootRight == null){
            return true;
        }
        if(rootLeft!=null&&rootRight == null||rootLeft==null&&rootRight != null){
            return false;
        }
        return rootLeft.val == rootRight.val && isSymmetricChild(rootLeft.left,rootRight.right) && isSymmetricChild(rootLeft.right,rootRight.left);
    }

14.二叉树的构建及遍历

import java.util.Scanner;
//没太懂
class TreeNode{
    public char val;
    public TreeNode left;
    public TreeNode right;
    public TreeNode(char val){
        this.val = val;
    } 
}
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static int i = 0;
    public static TreeNode createTree(String str){
        TreeNode root = null;
        if(str.charAt(i) != '#'){
            root = new TreeNode(str.charAt(i));//创建根
            i++;
            //创建左树和右树
            root.left = createTree(str);
            root.right = createTree(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[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNextLine()) {
            String str = in.nextLine();
            TreeNode root = createTree(str);
            inOrder(root);
        }
    }
}

15.二叉树的分层遍历

public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> ret = new ArrayList<>();
        if(root == null){
            return ret;
        }
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while(!queue.isEmpty()){
            List<Integer> curRow = new ArrayList<>();
            int size = queue.size();
            while(size!=0){
                TreeNode cur = queue.poll();
                curRow.add(cur.val);
                if(cur.left!=null){
                    queue.offer(cur.left);
                }
                if(cur.right!=null){
                    queue.offer(cur.right);
                }
                size--;
            }
            ret.add(curRow);
            
        }
        return ret;
    }

16.给定一个二叉树, 找到该树中两个指定节点的最近公共祖先

//还可以使用两个链表求交点,但是前提是每个节点知道parent
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root == null){
            return null;
        }
        if(root == p || root == q){
            return root;
        }
        TreeNode leftTree = lowestCommonAncestor(root.left,p,q);
        TreeNode rightTree = lowestCommonAncestor(root.right,p,q);
        if(leftTree != null && rightTree != null){
            return root;
        }
        if(leftTree != null){
            return leftTree;
        }
        if(rightTree != null){
            return rightTree;
        }
        return null;
    }

17.二叉树搜索树转换成排序双向链表

private TreeNode prev = null;
    //中序遍历二叉搜索树就是排序的
    public void converChild(TreeNode root){
        if(root == null){
            return;
        }
        converChild(root.left);
        root.left = prev;
        if(prev != null){
            prev.right = root;
        }
        prev = root;
        converChild(root.right);
    }
    public TreeNode Convert(TreeNode pRootOfTree) {
        if(pRootOfTree == null){
            return null;
        }
        converChild(pRootOfTree);
        TreeNode cur = pRootOfTree;
        while(cur.left != null){
            cur = cur.left;
        }
        return cur;
    }

18.根据一棵树的前序遍历与中序遍历构造二叉树

 public int perIndex = 0;
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        return buildTreeChild(preorder,inorder,0,inorder.length-1);
    }
    public TreeNode buildTreeChild(int[] preorder, int[] inorder,int inbegin,int inend) {
        if(inbegin > inend){
            return null;
        }
        TreeNode root = new TreeNode(preorder[perIndex]);
        int rootIndex = findIndex(inorder,preorder[perIndex],inbegin,inend);
        perIndex++;
        root.left = buildTreeChild(preorder,inorder,inbegin,rootIndex-1);
        root.right = buildTreeChild(preorder,inorder,rootIndex+1,inend);
        return root;
    }
    public int findIndex(int[] inorder,int key,int inbegin,int inend){
        for(int i = inbegin;i<=inend;i++){
            if(inorder[i] == key){
                return i;
            }
        }
        return -1;
    }

19.根据一棵树的中序遍历与后序遍历构造二叉树

public int perIndex = 0;
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        perIndex = postorder.length-1;
        return buildTreeChild(postorder,inorder,0,inorder.length-1);
    }
    public TreeNode buildTreeChild(int[] postorder, int[] inorder,int inbegin,int inend) {
        if(inbegin > inend){
            return null;
        }
        
        TreeNode root = new TreeNode(postorder[perIndex]);
        int rootIndex = findIndex(inorder,postorder[perIndex],inbegin,inend);
        perIndex--;
        root.right = buildTreeChild(postorder,inorder,rootIndex+1,inend);
        root.left = buildTreeChild(postorder,inorder,inbegin,rootIndex-1);
        return root;
    }
    public int findIndex(int[] inorder,int key,int inbegin,int inend){
        for(int i = inbegin;i<=inend;i++){
            if(inorder[i] == key){
                return i;
            }
        }
        return -1;
    }

20.二叉树创建字符串

public String tree2str(TreeNode root) {
        StringBuilder sb = new StringBuilder();
        if(root == null){
            return null;
        }
        tree2strChild(root,sb);
        return sb.toString();
    }
    public void tree2strChild(TreeNode root,StringBuilder sb) {
        if(root == null){
            return;
        }
        sb.append(root.val);
        if(root.left != null){
            sb.append("(");
            tree2strChild(root.left,sb);
            sb.append(")");
        }else{
            if(root.right == null){
                return;
            }else{
                sb.append("()");
            }
        }
        if(root.right!=null){
            sb.append("(");
            tree2strChild(root.right,sb);
            sb.append(")");
        }else{
            return;
        }
    }

21.二叉树前序非递归遍历实现

//遍历思路
     public List<Integer> preorderTraversal1(TreeNode root) {
         List<Integer> list = new ArrayList<>();
         if(root == null){
             return list;
         }
         return preorderTraversal1Child(root,list);
     }
     private List<Integer> preorderTraversal1Child(TreeNode root,List<Integer> list){
         if(root == null){
             return null;
         }
         list.add(root.val);
         preorderTraversal1Child(root.left,list);
         preorderTraversal1Child(root.right,list);
         return list;
     }
    //子问题思路
     public List<Integer> preorderTraversal2(TreeNode root) {
         List<Integer>  list = new ArrayList<>();
         if(root == null){
             return list;
         }
         list.add(root.val);
         List<Integer> leftList = preorderTraversal2(root.left);
         list.addAll(leftList);
         List<Integer> rightList = preorderTraversal2(root.right);
         list.addAll(rightList);
         return list;
     }
    //非递归实现
    public List<Integer> preorderTraversal3(TreeNode root){
        List<Integer> ret = new ArrayList<>();
        Stack<TreeNode> stack = new Stack<>();
        TreeNode cur = root;
        while(cur!=null || !stack.empty()){
            while(cur != null){
                stack.push(cur);
                ret.add(cur.val);
                cur = cur.left;
            }
            TreeNode top = stack.pop();
            cur = top.right;
        }
        return ret;
    }

22. 二叉树中序非递归遍历实现

//中序遍历
    public void inOrder(TreeNode root){
        if (root == null){
            return;
        }
        inOrder(root.left);
        System.out.print(root.val+" ");
        inOrder(root.right);
    }
    //非递归实现
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> ret = new ArrayList<>();
        Stack<TreeNode> stack = new Stack<>();
        TreeNode cur = root;
        while(cur!=null||!stack.empty()){
            while(cur!=null){
                stack.push(cur);
                cur = cur.left;
            }
            TreeNode top = stack.pop();
            ret.add(top.val);
            cur = top.right;
        }
        return ret;
    }

23.二叉树后序非递归遍历实现

//后序遍历
    public void postOrder(TreeNode root){
        if (root == null){
            return;
        }
        postOrder(root.left);
        postOrder(root.right);
        System.out.print(root.val+" ");
    }
    //非递归实现
    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> ret = new ArrayList<>();
        Stack<TreeNode> stack  = new Stack<>();
        TreeNode cur = root;
        TreeNode tmp = null;
        while(cur != null || !stack.empty()){
            while(cur != null){
                stack.push(cur);
                cur = cur.left;
            }
            TreeNode top = stack.peek();
            if(top.right == null || top.right == tmp){
                ret.add(top.val);
                stack.pop();
                tmp = top;
            }else{
                cur = top.right;
            }
        }
        return ret;
    }