__ 最近复习到了搜索二叉树,实现了搜索二叉树的一些主要的方法。写完后代码十分繁杂。于是对代码进行重构,分为Binarytree(父类),和BTS(子类)。本代码仅供学习参考使用,转载请附出处,搜索二叉树的代码在另一篇中。
~~Binary实现的主要方法有:求树的大小,求树是否为空,树的清空,前序遍历,中序遍历,后续遍历,层序遍历,求树的高度,求前驱,求后继,求是否为完全二叉树,以及简单的打印树状二叉树
其中加入了Visitor抽象类,用来实现二叉树打印随时停止,还有对数据的操作逻辑。
代码如下
package tree;
import java.util.LinkedList;
import java.util.Queue;
/**
* 树的重构
* @author 65481
*
* @param <E>
*/
public class BinaryTree<E> {
/*
成员变量
*/
protected int size;
protected Node<E> root;
/*
节点类
*/
protected static class Node<E>{
E element;
Node<E> left;
Node<E> right;
Node<E> parent;
public Node(E element,Node<E> parent) {
this.element = element;
this.parent = parent;
}
//是否为叶子节点
public boolean isLeaf() {
return left == null && right == null;
}
//是否有两个孩子
public boolean hasTwoChildren() {
return left != null && right != null;
}
}
/*
自定义抽象类 完成对数据的操作逻辑
boolean visit 如果返回true 则停止遍历
*/
public static abstract class Visitor<E>{
boolean stop;
abstract boolean visit(E element);
}
/*
节点数量方法
*/
public int size() {
return size;
}
/*
树是否为空方法
*/
public boolean isEmpty() {
return size == 0;
}
/*
清空树的方法
*/
public void clear() {
root = null;
size = 0;
}
/*
递归的前序遍历
*/
public void preorderTraversal(Visitor<E> visitor) {
if (visitor == null) {
return;
}
preorderTraversal(root,visitor);
}
//从根节点开始
private void preorderTraversal(Node<E> node,Visitor<E> visitor){
//递归出来的条件
if (node == null||visitor.stop) {
return;
}
if (visitor.stop) return;
visitor.stop = visitor.visit(node.element);
preorderTraversal(node.left,visitor);
preorderTraversal(node.right,visitor);
}
/*
递归的中序遍历
*/
public void midorderTraversal(Visitor<E> visitor) {
midorderTraversal(root,visitor);
}
private void midorderTraversal(Node<E> node,Visitor<E> visitor) {
//递归出来条件
if (node == null||visitor.stop) {
return;
}
midorderTraversal(node.left,visitor);
if (visitor.stop) return;
visitor.stop = visitor.visit(node.element);
midorderTraversal(node.right,visitor);
}
/*
后续遍历
*/
public void lastorderTraversal(Visitor<E> visitor) {
lastorderTraversal(root,visitor);
}
private void lastorderTraversal(Node<E> node,Visitor<E> visitor) {
//递归出来条件
if (node == null||visitor.stop) {
return;
}
lastorderTraversal(node.left,visitor);
lastorderTraversal(node.right,visitor);
if (visitor.stop) return;
visitor.stop = visitor.visit(node.element);
}
/*
层序遍历
*/
public void levelOrderTranversal(Visitor<E> visitor) {
if (root == null) {
return;
}
//创建队列
Queue<Node<E>> queue = new LinkedList<>();
queue.offer(root);
while(!queue.isEmpty()) {
//弹出头结点
Node<E> poll = queue.poll();
//打印
if (visitor.visit(poll.element)) {
return;
}
if (poll.left != null) {
queue.offer(poll.left);
}
if (poll.right != null) {
queue.offer(poll.right);
}
}
}
/*
树状打印二叉树
*/
@Override
public String toString() {
StringBuffer sb = new StringBuffer();
toString(root,sb,"");
return sb.toString();
}
/**
*
* @param node 节点
* @param sb 用于拼接
* @param prdix 此节点的前驱
*/
public void toString(Node<E> node,StringBuffer sb,String prefix) {
if (node == null) {
return;
}
toString(node.left,sb,prefix + "L--");
sb.append(prefix).append(node.element).append("\n");
toString(node.right,sb,prefix + "R--");
}
/*
前驱节点
*/
protected Node<E> predecessor(Node<E> node) {
//空节点
if (node == null) {
return null;
}
//前驱节点在左子树当中 left.right.right.right
Node<E> p = node.left;
if (p != null) {
while(p.right != null) {
p = p.right;
}
return p;
}
//从祖父节点中寻找前驱节点
while(node.parent != null && node == node.parent.left) {
node = node.parent;
}
return node.parent;
}
/*
后继节点
*/
protected Node<E> successor(Node<E> node) {
//空节点
if (node == null) {
return null;
}
//后继节点在右子树中 right.left.left.left
Node<E> p = node.right;
if (p != null) {
while(p.left != null) {
p = p.left;
}
return p;
}
//从祖父节点中寻找前驱
while(node.parent != null && node == node.parent.right) {
node = node.parent;
}
return node.parent;
}
/*
判断一棵树是完全二叉树
*/
public boolean isComplete() {
//根节点为空
if (root == null) { return false;}
//队列加入子节点
Queue<Node<E>> queue = new LinkedList<>();
queue.offer(root);
//判断标识 false为不是叶子节点 true为是叶子节点
boolean leaf = false;
//判断逻辑
while(!queue.isEmpty()) {
Node<E> node = queue.poll();
if (node.isLeaf() && !leaf) {
return false;
}
if (node.left != null) {
queue.offer(node.left);
}else if (node.right != null) {
return false;
}
if (node.right != null) {
queue.offer(node.right);
}else {
//剩下的节点都是叶子节点
leaf = true;
}
}
return true;
}
/*
二叉树的高度
*/
//非递归实现(使用了层序遍历)
public int height() {
if (root == null) {
return 0;
}
//树的高度
int height = 0;
//存储着每一层的元素数量
int levelSize = 1;
//创建队列
Queue<Node<E>> queue = new LinkedList<>();
queue.offer(root);
while(!queue.isEmpty()) {
//弹出头结点
Node<E> poll = queue.poll();
levelSize --;
if (poll.left != null) {
queue.offer(poll.left);
}
if (poll.right != null) {
queue.offer(poll.right);
}
//说明即将访问下一层
if (levelSize == 0) {
levelSize = queue.size();
height ++;
}
}
return height;
}
}