二叉树定义
二叉树是每个结点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)
二叉树子节点实例
private class BinaryNode<T> {
T element;
BinaryNode<T> left;
BinaryNode<T> right;
BinaryNode(T theElement) {
this(theElement, null, null);
}
BinaryNode(T element, BinaryNode<T> lt, BinaryNode<T> rt) {
this.element = element;
this.left = lt;
this.right = rt;
}
}
创建一个二叉树
public BinaryNode<T> creatBinaryPre(LinkedList<T> treeData) {
BinaryNode<T> root = null;
T data = treeData.removeFirst();
if (data != null) {
Log.d(TAG, data + "");
root = new BinaryNode<T>(data, null, null);
root.left = creatBinaryPre(treeData);
root.right = creatBinaryPre(treeData);
}
return root;
}
递归
先序遍历二叉树(递归)
①访问根节点
②线序遍历左子树
③先序遍历右子树
public void PrintBinaryTreePreRecur(BinaryNode<T> root) {
if (root != null) {
System.out.print(root.element);
PrintBinaryTreePreRecur(root.left);
PrintBinaryTreePreRecur(root.right);
}
}
中序遍历二叉树(递归)
①中序遍历左子树
②访问根节点
③中序遍历右子树
public void PrintBinaryTreeMidRecur(BinaryNode<T> root) {
if (root != null) {
PrintBinaryTreeMidRecur(root.left);
Log.e(TAG, root.element.toString());
PrintBinaryTreeMidRecur(root.right);
}
}
后序遍历二叉树(递归)
①后续遍历左子树
②后续遍历右子树
③访问跟结点
public void PrintBinaryTreeBacRecur(BinaryNode<T> root) {
if (root != null) {
PrintBinaryTreeBacRecur(root.left);
PrintBinaryTreeBacRecur(root.right);
Log.e(TAG, root.element.toString());
}
}
非递归
先序遍历二叉树(非递归)
思路:对于任意节点T,访问这个节点并压入栈中,然后访问节点的左子树, 遍历完左子树后,取出栈顶的节点T,再先序遍历T的右子树
public void PrintBinaryTreePreUnrecur(BinaryNode<T> root) {
BinaryNode<T> p = root;//p为当前节点
LinkedList<BinaryNode> stack = new LinkedList<>();
//栈不为空时,或者p不为空时循环
while (p != null || !stack.isEmpty()) {
//当前节点不为空。访问并压入栈中。并将当前节点赋值为左儿子
if (p != null) {
stack.push(p);
System.out.print(p.element);
p = p.left;
}
//当前节点为空:
// 1、当p指向的左儿子时,此时栈顶元素必然是它的父节点
// 2、当p指向的右儿子时,此时栈顶元素必然是它的爷爷节点
//取出栈顶元素,赋值为right
else {
p = stack.pop();
p = p.right;
}
}
}
中序遍历二叉树(非递归)
先将T入栈,遍历左子树;遍历完左子树返回时,栈顶元素应为T, 出栈,访问T->data,再中序遍历T的右子树。
public void PrintBinaryTreeMidUnrecur(BinaryNode<T> root) {
BinaryNode<T> p = root;//p为当前节点
LinkedList<BinaryNode> stack = new LinkedList<>();
//栈不为空时,或者p不为空时循环
while (p != null || !stack.isEmpty()) {
//当前节点不为空。压入栈中。并将当前节点赋值为左儿子
if (p != null) {
stack.push(p);
p = p.left;
}
//当前节点为空:
// 1、当p指向的左儿子时,此时栈顶元素必然是它的父节点
// 2、当p指向的右儿子时,此时栈顶元素必然是它的爷爷节点
//取出并访问栈顶元素,赋值为right
else {
p = stack.pop();
System.out.print(p.element);
p = p.right;
}
}
}
层次遍历二叉树/宽度优先遍历(非递归)
public void PrintBinaryTreeLayerUnrecur(BinaryNode<T> root) {
LinkedList<BinaryNode> queue = new LinkedList<>();
BinaryNode<T> p;
queue.push(root);
while (!queue.isEmpty()) {
p = queue.removeFirst();
System.out.print(p.element);
if (p.left != null)
queue.addLast(p.left);
if (p.right != null)
queue.addLast(p.right);
}
}
按层打印二叉树
public void printTopBottom(BinaryNode<T> root) {
LinkedList<BinaryNode> queue = new LinkedList<>();
int current;//当前层 还未打印的结点个数
int next;//下一层结点个数
queue.push(root);
BinaryNode<T> p;
current = 1;
next = 0;
while (!queue.isEmpty()) {
p = queue.removeFirst();
System.out.print(p.element);
current--;
if (p.left != null) {
queue.addLast(p.left);
next++;
}
if (p.right != null) {
queue.addLast(p.right);
next++;
}
if (current == 0) {
System.out.println();
current = next;
next = 0;
}
}
}