分治法在二叉树遍历中的应用
二叉树本身就是由两个更小的部分组成–左子树和右子树,所以二叉树的问题非常适合用分治法来解决。
二叉树的高度:从叶子到根之间的最长路径。我们可以理解为根的左子树高度和右子树高度加1(加1代表根所在的层)。
定义空树的高度为-1
private static int height(Node node) {
if (node == null) {
return -1;
}
return Math.max(height(node.l), height(node.r)) + 1;
}
T(n) = T(left) + T(right) + 1由递推式可得时间复杂度为O(n)
二叉树遍历:
/**
* 先序遍历
* */
private static void preorder(Node node) {
System.out.print(node.v + " ");
if (node.l != null)
preorder(node.l);
if (node.r != null)
preorder(node.r);
}
/**
* 中序遍历
* */
private static void midorder(Node node) {
if (node.l != null)
preorder(node.l);
System.out.print(node.v + " ");
if (node.r != null)
preorder(node.r);
}
/**
* 后序遍历
* */
private static void nextorder(Node node) {
if (node.l != null)
preorder(node.l);
if (node.r != null)
preorder(node.r);
System.out.print(node.v + " ");
}
完整代码:
class Node {
int v;
Node l;
Node r;
public Node(int v) {
this.v = v;
}
}
public class Main {
public static Node root;
private static int height(Node node) {
if (node == null) {
return -1;
}
return Math.max(height(node.l), height(node.r)) + 1;
}
private static boolean insert(Node node) {
if (root == null) {
root = node;
return true;
}
Node cur = root;
while (cur != null) {
if (node.v > cur.v) {
if (cur.r == null) {
cur.r = node;
return true;
}
cur = cur.r;
} else {
if (cur.l == null) {
cur.l = node;
return true;
}
cur = cur.l;
}
}
return false;
}
/**
* 先序遍历
* */
private static void preorder(Node node) {
System.out.print(node.v + " ");
if (node.l != null)
preorder(node.l);
if (node.r != null)
preorder(node.r);
}
/**
* 中序遍历
* */
private static void midorder(Node node) {
if (node.l != null)
preorder(node.l);
System.out.print(node.v + " ");
if (node.r != null)
preorder(node.r);
}
/**
* 后序遍历
* */
private static void nextorder(Node node) {
if (node.l != null)
preorder(node.l);
if (node.r != null)
preorder(node.r);
System.out.print(node.v + " ");
}
public static void main(String[] args) {
/**
* 插入
* */
insert(new Node(20));
insert(new Node(10));
insert(new Node(30));
/**
* 前序遍历
* */
preorder(root);
nextorder(root);
midorder(root);
System.out.println(height(root));
}
}
当然,并非所有关于二叉树的算法都需要遍历两颗子树,诸如二叉树的查找、插入、删除操作只需要遍历其中一棵,有兴趣的读者可以参考减治法在查找算法中的应用(JAVA)–二叉查找树的查找、插入、删除这篇文章。
关于二叉树感兴趣的朋友还可以继续学习一篇文章搞定面试中的二叉树题目(java实现)