二叉树的相关题目

二叉树的相关题目

二叉树的相关概念及其实现判断

如何判断一棵树是否是搜索二叉树?

搜索二叉树

对于每一棵子树来说,都满足,左树都比节点小,右树都比节点大的,就是搜索二叉树。

判断中序遍历是不是都是升序的,如果是那就是搜索二叉树

public static int preValue = Integer.MIN_VALUE;

public static boolean isBST(Node head) {
    if (head == null) {
        return true;
    }
    boolean isleftBST = isBST(head.left);
    if (!isleftBST){
        return false;
    }
    if (head.value <= preValue) {
        return false;
    }else {
        preValue = head.value;
    }
    return isBST(head.right);
}
public static boolean isBST3(Node head) {
    if (head != null) {
        int preValue = Integer.MIN_VALUE;
        Stack<Node> stack = new Stack<Node>();
        while (!stack.isEmpty() || head != null) {
            if (head != null) {
                stack.push(head);
                head = head.left;
            } else {
                head = stack.pop();
                if (head.value <= preValue) {
                    return false;
                }else {
                    preValue = head.value;
                }
                head = head.right;
            }
        }
    }
    return true;
}
判断是不是完全二叉树

按照宽度遍历

1)如果遇到有右孩子,没有左孩子,那就返回false。

2)第一个条件不存在的情况下,遇到了第一个左右孩子不双全的情况,那么接下来的所有节点都必须是叶节点。否则false

public static boolean isCBT(Node head) {
   if (head == null) {
      return true;
   }
   LinkedList<Node> queue = new LinkedList<>();
   boolean leaf = false;  //表示左右孩子不双全事件是否发生,发生之后就一直是true了
   Node l = null;
   Node r = null;
   queue.add(head);
   while (!queue.isEmpty()) {
      head = queue.poll();
      l = head.left;
      r = head.right;
      if ((leaf && (l != null || r != null)) || (l == null && r != null)) {
         return false;
      }
      if (l != null) {
         queue.add(l);
      }
      if (r != null) {
         queue.add(r);
      } else {
         leaf = true;
      }
   }
   return true;
}
判断是满二叉树

统计最大深度 D

统计节点数 N

如果N = 2^D -1,那么就是满二叉树

判断是平衡二叉树

对于任何一个子树来说,它的左树高度和右树高度差不能超过1。

那么它的左子树和右子树也是平衡的二叉树。

几个条件都成立,就是平衡二叉树

public static boolean isBalanced(Node head) {
   return process(head).isBalanced;
}

public static class ReturnType {
   public boolean isBalanced;
   public int height;

   public ReturnType(boolean isB, int hei) {
      isBalanced = isB;
      height = hei;
   }
}

public static ReturnType process(Node x) {
   if (x == null) {
      return new ReturnType(true, 0);
   }
   ReturnType leftData = process(x.left);
   ReturnType rightData = process(x.right);
   int height = Math.max(leftData.height, rightData.height) + 1;
   boolean isBalanced = leftData.isBalanced && rightData.isBalanced
         && Math.abs(leftData.height - rightData.height) < 2;
   return new ReturnType(isBalanced, height);
}

树型DP问题,可以使用递归的套路。 一般面试题通常可以这样做。 ,没法优化的问题,一般不会考。

最低公共祖先节点

给定两个二叉树的节点node1和node2,找到他们的最低公共祖先节点。也就是往上最初汇聚的点。

  • 生成一个往上的链。一个节点的,父节点信息链
  • 遍历的时候找公共祖节点
public static Node lowestAncestor(Node head, Node o1, Node o2) {
   if (head == null || head == o1 || head == o2) {
      return head;
   }
   Node left = lowestAncestor(head.left, o1, o2);
   Node right = lowestAncestor(head.right, o1, o2);
   if (left != null && right != null) {
      return head;
   }
   return left != null ? left : right;
}

后继节点

中序遍历中一个节点的下一个节点,叫它的后继节点

前驱节点,前一个节点

【 题目】 现在有一种新的二叉树节点类型如下:
public class Node {
public int value;
public Node left;
public Node right;
public Node parent;
public Node(int val) {
value = val;
}
}

该结构比普通二叉树节点结构多了一个指向父节点的parent指针。假设有一棵Node类型的节点组成的二叉树, 树中每个节点的parent指针都正确地指向自己的父节点, 头节点的parent指向null。
只给一个在二叉树中的某个节点node, 请实现返回node的后继节点的函数。
在二叉树的中序遍历的序列中, node的下一个节点叫作node的后继节点。

  • 如果x有右树,那么左就是它的后继
  • 如果没有右树,那么向上走,直到自己是左孩子的时候,这个祖节点就是后继。但是如果自己一直不是左孩子,那么它的后继是null

序列化和反序列化

就是内存里的一棵树如何变成字符串形式, 又如何从字符串形式变成内存里的树
如何判断一颗二叉树是不是另一棵二叉树的子树?

可以规定先建立左子树,再建立右子树。

public static String serialByPre(Node head) {
   if (head == null) {
      return "#!";
   }
   String res = head.value + "!";
   res += serialByPre(head.left);
   res += serialByPre(head.right);
   return res;
}

public static Node reconByPreString(String preStr) {
   String[] values = preStr.split("!");
   Queue<String> queue = new LinkedList<String>();
   for (int i = 0; i != values.length; i++) {
      queue.offer(values[i]);
   }
   return reconPreOrder(queue);
}

public static Node reconPreOrder(Queue<String> queue) {
   String value = queue.poll();
   if (value.equals("#")) {
      return null;
   }
   Node head = new Node(Integer.valueOf(value));
   head.left = reconPreOrder(queue);
   head.right = reconPreOrder(queue);
   return head;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

写代码的信哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值