二叉树经典面试题总结(完全二叉树、判断两棵树是否相同、另一棵树的子树、平衡二叉树、对称二叉树、根据二叉树创建字符串)

二叉树的链式存储结构是指,用链表来表示一棵二叉树,即用链来指示元素的逻辑关系。 通常的方法是链表中每个结点由三个域组成,数据域和左右指针域,左右指针分别用来给出该结点左孩子和右孩子所在的链结点的存储地址 。链式结构又分为二叉链和三叉链,这篇博客重在研究二叉链。

  • 二叉树的链式存储结构如下图所示:
    在这里插入图片描述
  • 以下述二叉树为例,它的链式存储结构如下:
    在这里插入图片描述
    在这里插入图片描述
    可以看得出来二叉树的链式存储和链表基本是一样的。
  • 下面是自己总结的一些关于二叉树的经典笔试面试题,仅供大家参考:
package com.xxx;

import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;

/**
 * Description: 二叉树
 * Author: admin
 * Create: 2019-06-06 20:09
 */
public class TestBinaryTree {

    class TreeNode {
        char value;
        TreeNode left;
        TreeNode right;

        public TreeNode(char value) {
            this.value = value;
        }
    }

    public int i = 0;
    //根据字符串创建二叉树
    public TreeNode createTestTree(String s) {
        TreeNode root = null;
        if (s.charAt(i) != '#') {
            root = new TreeNode(s.charAt(i));
            i++;
            root.left = createTestTree(s);
            root.right = createTestTree(s);
        }else {
            i++;
        }
        return root;
    }

    //结点个数
    public int getSize(TreeNode root) {
        if (root == null) {
            return 0;
        }
        return getSize(root.left) + getSize(root.right) + 1;
    }

    //叶子节点的个数
    public int getLeafSize(TreeNode root) {
        if (root == null) {
            return 0;
        }
        if (root.left == null && root.right == null) {
            return 1;
        }
        return getLeafSize(root.left) + getLeafSize(root.right);
    }

    //第k层节点个数
    public int getKLevelSize(TreeNode root, int k) {
        if (root == null) {
            return 0;
        }else if (k == 1) {
            return 1;
        }
        return getKLevelSize(root.left, k-1) + getKLevelSize(root.right, k-1);
    }

    //依次在二叉树的根、左子树、右子树中查找value,如果找到,返回结点,否则返回null
    public TreeNode find(TreeNode root, int value) {
        if (root == null) {
            return null;
        }
        if (root.value == value) {
            return root;
        }
        TreeNode ret = find(root.left, value);
        if (ret != null) {
            return ret;
        }
        ret = find(root.right, value);
        if (ret != null) {
            return ret;
        }
        return null;
    }

    //二叉树的高度
    public int height(TreeNode root) {
        if (root == null) {
            return 0;
        }else {
            int leftHeight = height(root.left);
            int rightHead = height(root.right);
            return (leftHeight > rightHead ? leftHeight : rightHead) + 1;
        }
    }

    //判断一棵树是否是完全二叉树,返回0代表是完全二叉树
    public int binaryTreeComplete(TreeNode root) {
        Queue<TreeNode> queue = new LinkedList<>();
        if (root != null) {
            queue.offer(root);
        }
        while (!queue.isEmpty()) {
            TreeNode top = queue.poll();
            if (top != null) {
                queue.offer(root.left);
                queue.offer(root.right);
            }else {
                break;
            }
        }
        while (!queue.isEmpty()) {
            if (queue.peek() == null) {
                queue.poll();
            }else {
                return -1;
            }
        }
        return 0;
    }

    //检查两棵树是否相同
    public boolean isSameTree(TreeNode p, TreeNode q) {
        if (p == null && q == null) {
            return true;
        }
        if ((p == null && q != null) || (p != null && q == null)) {
            return false;
        }
        if (p.value != q.value) {
            return false;
        }
        return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
    }

    //另一棵树的子树
    public boolean isSubtree(TreeNode s, TreeNode t) {
        if (s == null || t == null) {
            return false;
        }
        if (isSameTree(s, t)) {
            return true;
        }else if (isSubtree(s.left, t)) {
            return true;
        } else if (isSubtree(s.right, t)) {
            return true;
        }else {
            return false;
        }
    }

    //判断一颗二叉树是否是平衡二叉树  O(n^2)
    public boolean isBalanced(TreeNode root) {
        if (root == null) {
            return true;
        }else {
            int leftHeight = height(root.left);
            int rightHeight = height(root.right);
            return Math.abs(leftHeight - rightHeight) < 2
                    && isBalanced(root.left) && isBalanced(root.right);
        }
    }

    //对称二叉树
    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;
        }
        return leftTree.value == rightTree.value
                && 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);
    }

    //根据二叉树创建字符串
    public void tree2strChild(TreeNode t, StringBuilder sb) {
        if (t == null) {
            return;
        }
        sb.append(t.value);

        if (t.left != null) {
            sb.append("(");
            tree2strChild(t.left, sb);
            sb.append(")");
        }else {
            if (t.right == null) {
                return;
            }else {
                sb.append("()");
            }
        }

        if (t.right == null) {
            return;
        }else {
            sb.append("(");
            tree2strChild(t.right, sb);
            sb.append(")");
        }
    }
    public String tree2str(TreeNode t) {
        StringBuilder sb = new StringBuilder();
        tree2strChild(t, sb);
        return sb.toString();
    }
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值