一、二叉树的遍历:
二叉树不是线性结构,遍历起来就比较复杂。遍历:按照一定的顺序不重复的访问到这个集合的所有元素
-
1.前序遍历:先访问(打印,修改,比较,等等。。。)根节点,递归遍历左子树,递归遍历右子树
-
2.中序遍历:先递归遍历左子树,访问根节点,递归遍历右子树,
-
3.后序遍历:先递归遍历左子树,遍历右子树,访问根节点
-
4.层序遍历:一层一层往下遍历,每层从左到右访问。
- 遍历结果规律:
-
1.先序遍历第一个访问的节点一定是根节点
-
2.后序遍历最后一个访问的结点一定是根节点
-
3.中序遍历和后序遍历第一个访问的节点就是树的最左侧节点,
-
4.针对先序后续遍历来说,子树的遍历结果是嵌套在整个遍历结果中的。
-
5.中序遍历,左子树的遍历结果在根节点的左侧,右子树的遍历结果在根节点的右侧。
二、实现二叉树的基本方法
static class Testtree1 {
class Nodes {
private char val;
private Nodes left;
private Nodes right;
public Nodes(char val) {
this.val = val;
}
public char getVal() {
return val;
}
public void setVal(char val) {
this.val = val;
}
public Nodes getLeft() {
return left;
}
public void setLeft(Nodes left) {
this.left = left;
}
public Nodes getRight() {
return right;
}
public void setRight(Nodes right) {
this.right = right;
}
}
class Testtree1 {
//简单的创建一个二叉树
public static Nodes build() {
Nodes a = new Nodes('a');
Nodes b = new Nodes('b');
Nodes c = new Nodes('c');
Nodes d = new Nodes('d');
Nodes e = new Nodes('e');
Nodes f = new Nodes('f');
Nodes g = new Nodes('g');
Nodes h = new Nodes('h');
a.setLeft(b);
a.setRight(c);
b.setLeft(d);
b.setRight(e);
c.setLeft(f);
c.setRight(g);
d.setLeft(h);
return a;
}
//前序遍历
public static void preOrder(Nodes root) {
if (root == null) {
return;
}
System.out.print(root.getVal() + " ");
preOrder(root.getLeft());
preOrder(root.getRight());
}
//中序遍历
public static void inOrder(Nodes root) {
if (root == null) {
return;
}
inOrder(root.getLeft());
System.out.print(root.getVal() + " ");
inOrder(root.getRight());
}
//后序遍历
public static void posOrder(Nodes root) {
if (root == null) {
return;
}
posOrder(root.getLeft());
posOrder(root.getRight());
System.out.print(root.getVal() + " ");
}
//求二叉树所有节点
public static int size(Nodes root) {
if (root == null) {
return 0;
}
//整个树的结点=根节点(1)+左子树节点+右子树节点
return 1 + size(root.getLeft()) + size(root.getRight());
}
//求二叉树叶子节点
public static int leafSize(Nodes root) {
if (root == null) {
return 0;
}
if (root.getRight() == null && root.getLeft() == null) {
return 1;
}
return leafSize(root.getLeft()) + leafSize(root.getRight());
}
//求二叉树第K层的节点。
public static int KLevelSize(Nodes root, int k) {
if (k == 0 || root == null) return 0;
if (k == 1) return 1;
return KLevelSize(root.getLeft(), k - 1) + KLevelSize(root.getRight(), k - 1);
}
//在二叉树中查找指定元素
public static Nodes find(Nodes root, char val) {
if (root == null) {
System.out.println("没有该元素");
return null;
}
if (root.getVal() == val) {
System.out.println(val);
return root;
}
//分别递归的去查找左右子树
Nodes result = find(root.getLeft(), val);
if (result != null) return result;
return find(root.getRight(), val);
}
//层序遍历
public static void levalOrder(Nodes root) {
Queue<Nodes> queue = new LinkedList<>();
queue.offer(root);
while(!queue.isEmpty()){
Nodes a = queue.poll();
System.out.print(a.getVal() + " ");
if (a.getLeft() != null) {
queue.offer(a.getLeft());
}
if (a.getRight() != null) {
queue.offer(a.getRight());
}
}
}
//判断一个属是不是完全二叉树
public static boolean isCompleteTree(Nodes root) {
if (root == null) return false;
Queue<Nodes> queue = new LinkedList<>();
queue.offer(root);
boolean isSecond = false;
while (!queue.isEmpty()) {
//取出队首元素同时出队列
Nodes a = queue.poll();
//针对当前节点进行访问(判断是否符合完全二叉树的要求)
if (!isSecond) {
if (a.getLeft() != null && a.getRight() != null) {
queue.offer(a.getLeft());
queue.offer(a.getRight());
} else if (a.getLeft() == null && a.getRight() != null) {
return false;
} else if (a.getLeft() != null && a.getRight() == null) {
isSecond = true;
queue.offer(a);
} else if (a.getLeft() == null && a.getRight() == null) {
isSecond = true;
}
} else {
if (a.getRight() != null || a.getLeft() != null) {
return false;
} else {
a = queue.poll();
}
}
}
return true;
}
}