一、如果树中的每个节点最多只能有两个子节点,这样的树就称为“二叉树”
二、二叉排序树:
- 若它的左子树不空,则左子树上所有节点的值均小于它的根节点的值;
- 若它的右子树不空,则右子树上所有节点的值均大于它的根节点的值;
- 它的左右子树也分别为二叉排序树。
平衡二叉树(AVL):
1)左子树和右子树都是平衡二叉树;
2)左子树和右子树的深度(高度)之差的绝对值不超过1。
重在高度差不超过1
红黑树:
特性:
节点是红色或黑色
根节点一定是黑色
每个叶节点都是黑色的空节点(NIL节点)
每个红节点的两个子节点都是黑色的
(从每个叶子到跟的所有路径上不能有两个连续的红节点)
(即对于层来说除了NIL节点,红黑节点是交替的,第一层是黑节点那么其下一层肯定都是红节点,反之一样)
从任一节点到其每个叶子节点的所有路径都包含相同数目的黑色节点
正是由于这些原因使得红黑树是一个平衡二叉树
什么是红黑树?
传送门
变色——左旋——变色——右旋——变色
TreeMap TreeSet HashMap
树的各种前中后遍历,以及不递归实现
1. 判断两个树是否相同
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public boolean isSameTree(TreeNode p, TreeNode q) {
if (p == null && q == null) {
return true;
} else if (p != null && q != null) {
if (p.val == q.val) {
return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
} else {
return false;
}
} else {
return false;
}
}
}
2. 判断是否是对称树
class Solution {
public boolean isSymmetric(TreeNode root) {
return isMirror(root,root);
}
//利用外部的一个函数判断
//1. 如果都是空,true
//2 如果一个为空,false
//3. 都不为空,递归判断
//4. 先判断t1.val和t2.val
//5. 再判断right 和left节点
//只要4和5一个不为true,就是false
public boolean isMirror(TreeNode t1, TreeNode t2) {
if (t1 == null && t2 == null) return true;
if (t1 == null || t2 == null) return false;
return (t1.val == t2.val)
&& isMirror(t1.right, t2.left)
&& isMirror(t1.left, t2.right);
}
}
3. 求树的最大深度
int maxDepth = 0;
public int maxDepth(TreeNode root) {
if (root == null) {
return 0;
} else {
int left_height = maxDepth(root.left);
int right_height = maxDepth(root.right);
maxDepth = java.lang.Math.max(left_height, right_height) + 1;
return maxDepth;
}
}
4、顺序打印树的每一层
package shuju;
import java.util.LinkedList;
import java.util.Queue;
public class Tree {
TreeNode last;
TreeNode nlast;
public void printTree(TreeNode root) {
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
last = root;
nlast = root;
while (!queue.isEmpty()) {
TreeNode t = queue.peek();
System.out.print(queue.poll().data + " ");
if (t.left != null) {
queue.add(t.left);
nlast = t.left;
}
if (t.right != null) {
queue.add(t.right);
nlast = t.right;
}
// 如果当前输出结点是最右结点,那么换行
if (last == t) {
System.out.println();
last = nlast;
}
}
}
public static void main(String[] args) {
// 构建二叉树
TreeNode root = new TreeNode(1);
root.left = new TreeNode(2);
root.right = new TreeNode(3);
root.left.left = new TreeNode(4);
root.right.left = new TreeNode(5);
root.right.right = new TreeNode(6);
root.right.left.left = new TreeNode(7);
root.right.left.right = new TreeNode(8);
Tree test = new Tree();
test.printTree(root);
}
}
原理是:
1.用一个linkedList表示队列,poll和add分别表示出队列和入队列
2. 第一次直接将root放入队列,打印,用一个TreeNode取出来
3. 声明一个全局的下一层最右边的节点nlast
4. 如果root左边有值,nlast=t.left
5. 如果root右边有值,nlast=t.right
6. 45两步能保证如果root右边有值,nlast就为最右边的值
7. 声明一个当前层的最右节点last
8. last开始为root,如果last==t,last =nlast=3 进行下一层遍历
9. — 打印了一个1,队列里面有left2 和right3
10. 10.然后t =left2 先打印2,nlast=left2.left=4, 而且last3!=left2
11. 基础t =right3 打印3 nlast =4=5,last =t 进行下一层
12. 大概就是这样的流程
如果想要翻转顺序,第一层从左往右,第二层从右向左