节点定义
public static class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode() {
}
TreeNode(int val) {
this.val = val;
}
TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
}
带有父节点的节点定义
public static class Node {
int val;
Node left;
Node right;
Node parent;
public Node(int val) {
this.val = val;
}
}
二叉树前中后遍历(递归版)
/**
* 递归版前中后遍历
*/
//二叉树前序遍历(递归版)
public static List<Integer> preOrder(TreeNode root) {
List<Integer> list = new ArrayList<>();
po(root, list);
return list;
}
private static void po(TreeNode root, List<Integer> list) {
if (root == null) {
return;
}
list.add(root.val);
po(root.left, list);
po(root.right, list);
}
//二叉树中序遍历(递归版)
public static List<Integer> inOrder(TreeNode root) {
List<Integer> list = new ArrayList<>();
io(root, list);
return list;
}
private static void io(TreeNode root, List<Integer> list) {
if (root == null) {
return;
}
po(root.left, list);
list.add(root.val);
po(root.right, list);
}
//二叉树后序遍历(递归版)
public static List<Integer> postOrder(TreeNode root) {
List<Integer> list = new ArrayList<>();
pso(root, list);
return list;
}
private static void pso(TreeNode root, List<Integer> list) {
if (root == null) {
return;
}
po(root.left, list);
po(root.right, list);
list.add(root.val);
}
二叉树前中后遍历(非递归版)
/**
* 非递归版前中后遍历
*/
//二叉树前序遍历(非递归版)
public static List<Integer> preOrder1(TreeNode root) {
List<Integer> list = new ArrayList<>();
if (root == null) return list;
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while (!stack.isEmpty()) {
TreeNode cur = stack.pop();
list.add(cur.val);
if (cur.right != null) {
stack.push(cur.right);
}
if (cur.left != null) {
stack.push(cur.left);
}
}
return list;
}
//二叉树中序遍历(非递归版)
public static List<Integer> inOrder1(TreeNode root) {
List<Integer> list = new ArrayList<>();
if (root == null) return list;
Stack<TreeNode> stack = new Stack<>();
while (!stack.isEmpty() || root != null) {
if (root != null) {
stack.push(root);
root = root.left;
} else {
root = stack.pop();
list.add(root.val);
root = root.right;
}
}
return list;
}
//二叉树后序遍历(非递归版)
public static List<Integer> postOrder1(TreeNode root) {
List<Integer> list = new ArrayList<>();
if (root == null) return list;
//准备两个栈 一个使用栈 一个收集栈
Stack<TreeNode> stack1 = new Stack<>();
Stack<TreeNode> stack2 = new Stack<>();
stack1.push(root);
while (!stack1.isEmpty()) {
TreeNode cur = stack1.pop();
stack2.push(cur);
if (cur.left != null) {
stack1.push(cur.left);
}
if (cur.right != null) {
stack1.push(cur.right);
}
}
while (!stack2.isEmpty()) {
list.add(stack2.pop().val);
}
return list;
}
判断搜索二叉树
/**
* 如何判断一棵二叉树是否是搜索二叉树
* (搜索二叉树中序遍历为升序排列)
*/
//方法1 利用搜索二叉树中序遍历为升序排列(递归版本)
public static boolean isBST(TreeNode root) {
int prevalue = Integer.MIN_VALUE;
if (root == null) {
return true;
}
boolean isLeftBST = isBST(root.left);
if (root.val <= prevalue) {
return false;
} else {
prevalue = root.val;
}
return isBST(root.right);
}
//方法1 利用搜索二叉树中序遍历为升序排列(非递归版本)
public static boolean isBST1(TreeNode root) {
int preValue = Integer.MIN_VALUE;
Stack<TreeNode> stack = new Stack<>();
while (stack != null || root != null) {
if (root != null) {
stack.push(root);
root = root.left;
} else {
root = stack.pop();
if (root.val <= preValue) {
return false;
} else {
preValue = root.val;
}
root = root.right;
}
}
return true;
}
//方法二:套路解题
/*套路解题(看需要左右树的什么信息)
1.需要左树是搜索二叉树
2.需要右树是搜索二叉树
3.左树的最大值
4.右树的最小值
*/
public static class ReturnType1 {
public boolean isBST;
public int max;
public int min;
public ReturnType1(boolean isBST, int max, int min) {
this.isBST = isBST;
this.max = max;
this.min = min;
}
}
public static boolean isBST2(TreeNode root) {
return process1(root).isBST;
}
public static ReturnType1 process1(TreeNode root) {
if (root == null) {
return null;
}
ReturnType1 leftType = process1(root.left);
ReturnType1 rightType = process1(root.right);
int max = root.val;
int min = root.val;
if (leftType != null) {
min = Math.min(min, leftType.min);
max = Math.max(max, leftType.max);
}
if (rightType != null) {
min = Math.min(min, rightType.min);
max = Math.max(max, rightType.max);
}
boolean isBST = true;
if (leftType != null && (leftType.isBST || leftType.max >= root.val)) {
isBST = false;
}
if (rightType != null && (rightType.isBST || rightType.min <= root.val)) {
isBST = false;
}
return new ReturnType1(isBST, min, max);
}
判断完全二叉树
/**
* 如何判断一棵二叉树是否是完全二叉树(BFS )
*/
/*1.任一节点 有右无左返回false;
2.在1不违规的前提下,如果遇到第一个左右不双全的节点,后续皆是叶子节点*/
public static boolean isCBT(TreeNode root) {
if (root == null) return true;
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
//定义一个标志位 专门看是否已经碰到过左右不双全的节点
Boolean leaf = false;
TreeNode l;
TreeNode r;
while (queue != null) {
TreeNode cur = queue.poll();
l = cur.left;
r = cur.right;
if (
(leaf && (l != null || r != null))
||
(l == null && r != null)
) {
return false;
}
if (l != null) {
queue.add(cur.left);
}
if (r != null) {
queue.add(cur.right);
}
if (l == null || r == null) {
leaf = true;
}
}
return true;
}
判断满二叉树
/**
* 如何判断一棵二叉树是否是满二叉树(BFS)
*/
/*套路解题(看需要左右树的什么信息)
1.需要左树是满二叉树
2.需要右树是满二叉树
*/
public static class ReturnType2 {
public int height;
public int nodes;
public ReturnType2(int height, int nodes) {
this.height = height;
this.nodes = nodes;
}
}
public boolean isFull(TreeNode root) {
return process2(root).nodes == Math.pow(2, process2(root).height);
}
public ReturnType2 process2(TreeNode root) {
if (root == null) {
return new ReturnType2(0, 0);
}
ReturnType2 leftType = process2(root.left);
ReturnType2 rightType = process2(root.right);
int height = Math.max(leftType.height, rightType.height) + 1;
int nodes = leftType.nodes + rightType.nodes + 1;
return new ReturnType2(height, nodes);
}
判断平衡二叉树
/**
* 如何判断一棵二叉树是否是平衡二叉树
*/
/*套路解题(看需要左右树的什么信息)
1.需要左树是平衡二叉树
2.需要右树是平衡二叉树
3.需要|左树高度-右树高度<=1|
*/
public static class ReturnType {
public boolean isBalanced;
public int height;
public ReturnType(boolean isBalanced, int height) {
this.isBalanced = isBalanced;
this.height = height;
}
}
public static boolean isBalanced(TreeNode root) {
return process(root).isBalanced;
}
private static ReturnType process(TreeNode root) {
if (root == null) {
return new ReturnType(true, 0);
}
ReturnType leftType = process(root.left);
ReturnType rightType = process(root.right);
int height = Math.max(leftType.height, rightType.height) + 1;
boolean isBalanced = leftType.isBalanced && rightType.isBalanced &&
Math.abs(leftType.height - rightType.height) <= 1;
return new ReturnType(isBalanced, height);
}
寻找最小公共祖先
/**
* 寻找最小公共祖先
*/
//方法1:将两节点的向上链都表示出来
public static TreeNode lca1(TreeNode root, TreeNode node1, TreeNode node2) {
HashMap<TreeNode, TreeNode> fatherMap = new HashMap<>();
fatherMap.put(root, root);
process3(root, fatherMap);
HashSet<TreeNode> set = new HashSet<>();
TreeNode cur = node1;
while (cur != fatherMap.get(cur)) {
set.add(cur);
cur = fatherMap.get(cur);
}
set.add(root);
cur = node2;
while (cur != fatherMap.get(cur)) {
if (set.contains(cur)) {
return cur;
}
cur = fatherMap.get(cur);
}
return root;
}
public static void process3(TreeNode root, HashMap<TreeNode, TreeNode> fatherMap) {
if (root == null) {
return;
}
fatherMap.put(root.left, root);
fatherMap.put(root.right, root);
process(root.left);
process(root.right);
}
//方法2
/*只有这两种情况
1.node1 是 node2 的lca 或 node2 是 node1 的lca
2.node1 和 node2 不互为lca
* */
public static TreeNode lca2(TreeNode root, TreeNode node1, TreeNode node2) {
if (root == null || root == node1 || root == node2) {
return root;
}
TreeNode left = lca2(root.left, node1, node2);
TreeNode right = lca2(root.right, node1, node2);
if (left != null && right != null) {
return root;
}
return left != null ? left : right;
}
寻找后继节点
/**
* 寻找后继节点
*/
public static Node getSuccessorNode(Node node) {
if (node == null) {
return node;
}
if (node.right != null) {
return getLeftMost(node.right);
} else {
Node parent = node.parent;
while (parent != null && parent.left != node) {
node = parent;
parent = node.parent;
}
return parent;
}
}
private static Node getLeftMost(Node node) {
if (node == null) {
return node;
}
while (node.left != null) {
node = node.left;
}
return node;
}
/**
* 序列化与反序列化
*/
public static void main(String[] args) {
TreeNode treeNode7 = new TreeNode(7);
TreeNode treeNode6 = new TreeNode(6);
TreeNode treeNode5 = new TreeNode(5);
TreeNode treeNode4 = new TreeNode(4);
TreeNode treeNode3 = new TreeNode(3, treeNode6, treeNode7);
TreeNode treeNode2 = new TreeNode(2, treeNode4, treeNode5);
TreeNode treeNode1 = new TreeNode(1, treeNode2, treeNode3);
List<Integer> list = inOrder1(treeNode1);
for (Integer i :
list) {
System.out.println(i);
}
System.out.println(isBST(treeNode1));
}
}