1 二叉树是树中的一种特殊情况,由一个根节点和两个互不相交分别被称为根节点的左子树和右子树组成。
代码如下:
定义一个节点类型,包括一个数据域,一个指向左孩子的指针,一个指向右孩子的指针。
1.1 构造一棵树时,因为一组前序或中序或后序不能构造出一颗的形状,我们约定,将一棵树补全,即没有左子树的节点构造一颗左子树,数据域为#,没有右子树的构造一颗右子树。得出前序遍历结果,用来构造树。
构造树的解释在代码中讲得较详细。可看代码。
public class BinaryTree<E> {
/**
* 树的根节点
*/
private Node<E> root;
/**
* 构造树的数据域
*/
private Object[] arrayData;
/**
* 树节点的最大个数
*/
private static final Integer MAX_SIZE = 1000;
private class Node<E> {
/**
* 数据域
*/
private E data;
/**
* 指向左孩子节点
*/
private Node<E> left;
/**
* 指向右孩子节点
*/
private Node<E> right;
public Node(E data, Node<E> left, Node<E> right) {
this.data = data;
this.left = left;
this.right = right;
}
}
public BinaryTree(Object[] arrayData) {
this.arrayData = new Object[1000];
System.arraycopy(arrayData, 0, this.arrayData, 0, arrayData.length);
}
// 数组索引
private Integer index = -1;
/**
* 创建一棵树, 说明:当数据域为#时表示不存在该节点,思路为沿着相对根节点依次向下递归,
* 左右子树机各为上一个的相对根节点的左右子树,同时该相对左右子树为相对根 节点,依次向下递归。
*
* @param root
* 相对节点
* @return 绝对根节点
*/
@SuppressWarnings("unchecked")
public Node<E> createTree(Node<E> root) {
index++;
if ("#".equals((String) arrayData[index])) {
root = null;
} else {
root = new Node<E>((E) arrayData[index], null, null);
root.left = createTree(root.left);
root.right = createTree(root.right);
}
return root;
}
/**
* 前序遍历
*
* @param root
* 相对根节点
*/
public void preOrder(Node<E> root) {
if (root != null) {
System.out.print(root.data + " ");
preOrder(root.left);
preOrder(root.right);
}
}
public static void main(String[] args) {
String[] obj = new String[] { "A", "B", "#", "D", "#", "#", "C", "#",
"#" };
BinaryTree<String> btree = new BinaryTree<String>(obj);
btree.root = btree.createTree(btree.root);
btree.preOrder(btree.root);
System.out.println();
btree.inOrder(btree.root);
System.out.println();
btree.postOrder(btree.root);
}
}
1.2 树的中序和后序遍历
/**
* 中序遍历
*
* @param root
* 相对根节点
*/
public void inOrder(Node<E> root) {
if (root != null) {
inOrder(root.left);
System.out.print(root.data + " ");
inOrder(root.right);
}
}
/**
* 后序遍历
*
* @param root
* 相对根节点
*/
public void postOrder(Node<E> root) {
if (root != null) {
postOrder(root.left);
postOrder(root.right);
System.out.print(root.data + " ");
}
}
1.3 树的层序遍历
/**
* 树的层序遍历
* 说明:定义一个队列,输出根节点的数据域,存在左右子树则入队,
*
* @param root
* 树的绝对根节点
*/
@SuppressWarnings("unchecked")
public void levelOrder(Node<E> root) {
// 定义一个队列,
Integer MAX_SIZE = 500;
Object[] obj = new Object[MAX_SIZE];
// 头指针指向第一个节点前一个,尾节点指向最后一个节点
Integer front = -1, rear = -1;
// 绝对根节点入队
obj[(++rear) % MAX_SIZE] = root;
while ((front % MAX_SIZE) != rear) {
// 当前出列的节点
root = ((Node<E>) obj[(++front) % MAX_SIZE]);
System.out.println(root.data);
// 有左子树则入队
if (root.left != null) {
obj[(++rear) % MAX_SIZE] = root.left;
}
// 有右子树则入队
if (root.right != null) {
obj[(++rear) % MAX_SIZE] = root.right;
}
}
}