二叉树的相关题目
二叉树的相关概念及其实现判断
如何判断一棵树是否是搜索二叉树?
搜索二叉树
对于每一棵子树来说,都满足,左树都比节点小,右树都比节点大的,就是搜索二叉树。
判断中序遍历是不是都是升序的,如果是那就是搜索二叉树
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;
}