1、树
public static class Node {
public int value;
public Node left;
public Node right;
public Node(int data) {
this.value = data;
}
}
2、先序遍历:根左右
中序遍历:左根右
后序遍历:左右根
3、递归方式实现树的遍历
public void preRecur(Node head)
{
if(head==null)
return;
system.out.println(head.value+" ");
preRecur(head.left);
preRecur(head.right);
}
4、非递归实现树的先序遍历
public static void preOrderUnRecur(Node head) {
System.out.print("pre-order: ");
if (head != null) {
Stack<Node> stack = new Stack<Node>();
stack.add(head);
while (!stack.isEmpty()) {
head = stack.pop();
System.out.print(head.value + " ");
if (head.right != null) {
stack.push(head.right);
}
if (head.left != null) {
stack.push(head.left);
}
}
}
System.out.println();
}
步骤:
(1)首先申请一个新的栈,记为stack
(2)记住将头节点head压入stack中
(3)每次从stack中弹出栈顶节点,记为cur,然后打印cur的节点值。
如果cur的右孩子不为空的话,将cur的右孩子先压入栈中。
最后如果cur的左孩子不为空,将cur的左孩子压入stack。
5、非递归实现树的中序遍历
public static void inOrderUnRecur(Node head) {
System.out.print("in-order: ");
if (head != null) {
Stack<Node> stack = new Stack<Node>();
while (!stack.isEmpty() || head != null) {
if (head != null) {
stack.push(head);
head = head.left;
} else {
head = stack.pop();
System.out.print(head.value + " ");
head = head.right;
}
}
}
System.out.println();
}
步骤:
(1)申请一个新的栈,记为stack,申请一个新的变量cur,初始时令cur等于头节点。
(2)先把cur节点压入栈中,对以cur节点为头的整棵树来说,依次把整棵树的左边界压入栈中,即不断令cur=cur.left,然后重复步骤(2)
(3)不断重复步骤2,直到发现cur为空,此时从stack中弹出一个节点,记为node,打印node的值,并让cur=node.right,然后继续重复步骤2.
(4)cur为空时,结束
6、非递归实现树的后序遍历
public static void posOrderUnRecur1(Node head) {
System.out.print("pos-order: ");
if (head != null) {
Stack<Node> s1 = new Stack<Node>();
Stack<Node> s2 = new Stack<Node>();
s1.push(head);
while (!s1.isEmpty()) {
head = s1.pop();
s2.push(head);
if (head.left != null) {
s1.push(head.left);
}
if (head.right != null) {
s1.push(head.right);
}
}
while (!s2.isEmpty()) {
System.out.print(s2.pop().value + " ");
}
}
System.out.println();
}
使用两个栈
(1)申请一个栈,记为s1,然后将头节点压入s1中
(2)从s1中弹出的节点记为cur,先把cur左孩子压入s1中,再把cur右孩子压入s1中
(3)在整个过程中,每一个从s1中弹出的节点都放进第二个栈s2中
(4)不断重复步骤2和3,直到s1为空,过程停止。
(5)从s2中依次弹出元素
7、二叉树按层遍历
宽度优先遍历----队列实现
8、按行打印二叉树
思路:
last:表示正在打印的当前行的最右节点
nlast:表示下一行的最右节点
队列
last第二层最右节点,nlast第三层最右节点,nlast虽每一层节点更新,节点值依次压入队列,last值弹出时,说明该换行了。
9、二叉树的序列化和反序列化
二叉树--字符串(序列化)
字符串--二叉树(反序列化)
先序遍历对二叉树进行序列化
(1)假设序列化结果为str,初始时str为空字符串
(2)先序遍历二叉树时如果遇到空节点,在str末位加上“#!”
(3)如果遇到不为空的节点,假设节点值为3,就在str末位加上“3!”
中序、后序、层次遍历都可以
10、二叉树的子树
11、二叉平衡树
空树是一颗平衡二叉树
如果一棵树不为空,并且其中所有的子树都满足各自的左子树和右子树的高度差都不超过1
判断是否为左子树:
左子树是否为平衡二叉树
左子树最深到哪一层,LH
右子树是否为平衡二叉树
右子树最深到哪一层,LR
LH和LR差值是否大于1
12、搜索二叉树
每棵子树的头节点的值都比各自左子树上的所有节点值大,也都比各自右子树上的所有节点值要小
搜索二叉树按照中序遍历得到的序列,一定是从小到大排列的
判断是否是搜索二叉树
中序遍历,看是否从小到大排列
13、满二叉树
除了最后一层的节点无任何节点外,剩下每一层上的节点都有两个子节点
满二叉树层数L,节点数N,则N=2的L次方-1
14、完全二叉树
指除了最后一层外,其他每一层的节点数都是满的,最后一层如果满了,则是满二叉树
最后一层如果不满,缺少的节点应完全集中在右边
判断是否是完全二叉树:
按层遍历二叉树,从左到右依次遍历
如果当前节点有右孩子,没有左孩子,直接返回fasle
如果当前节点不是左右孩子全有,那之后的节点必须都为叶子节点,否则返回false
15、后继节点和前驱节点
后继节点:中序遍历序列的下一个节点
前驱节点:中序遍历序列的上一个节点