作为新手,写了一个二叉树作练习,希望能得到大佬的指点。
package dataStructureSamples;
import java.util.ArrayList;
import java.util.List;
import javax.security.auth.Destroyable;
/**
* 二叉树
* @author Miko
*
*/
public class BinaryTree<T> implements Destroyable {
/**
* 树的数据。
*/
private T data;
/**
* 父节点。
*/
private BinaryTree<T> parent;
/**
* 左孩子节点。
* @see #setLeftChild(BinaryTree)s
*/
private BinaryTree<T> lchild;
/**
* 右孩子节点。
* @see #setRightChild(BinaryTree)
*/
private BinaryTree<T> rchild;
/**
* 构造一棵空树。
*/
public BinaryTree() {
data = null;
lchild = null;
rchild = null;
parent = null;
}
/**
* 构造一个叶子节点。
* @param data 数据值
*/
public BinaryTree(T data) {
this.data = data;
lchild = null;
rchild = null;
parent = null;
}
/**
* 获取树的数据。
* @return 树的数据
*/
public T getData() {
return data;
}
/**
* 设置父节点
* @param parent 父节点
*/
public void setParent(BinaryTree<T> parent) {
this.parent = parent;
}
/**
* 获取父节点。
* @return 父节点
*/
public BinaryTree<T> getParent(){
return parent;
}
/**
* 获取左孩子节点。
* @return 左孩子节点
*/
public BinaryTree<T> getLeftChild(){
return lchild;
}
/**
* 获取右孩子节点。
* @return 右孩子节点
*/
public BinaryTree<T> getRightChild(){
return rchild;
}
/**
* 获取节点的度。
* @return 节点的度
*/
public int getNodeDegree() {
int degree = 0;
if(lchild != null)
degree++;
if(rchild != null) {
degree++;
}
return degree;
}
/**
* 以先序查询指定索引的节点。<br>
* 如果查询空树则抛出<code>{@link NullPointerException}</code>。<br>
* 如果输入非法索引则抛出<code>{@link ArrayIndexOutOfBoundsException}</code>。<br>
* @param index 索引
* @return 节点
* @throws Exception
* @see #isEmptyTree()
* @see #size()
* @see #getAllTreesByPreOrder()
*/
public BinaryTree<T> getNodeByPreIndex(int index) throws Exception{
if(isEmptyTree()) {
throw new NullPointerException("不能从空节点中获取指定索引的节点。");
}else if(index >= size() || index < 0) {
throw new ArrayIndexOutOfBoundsException();
}else if(index == 0) {
return this;
}else {
int index2 = 0;
List<BinaryTree<T>> trees = getAllTreesByPreOrder();
for (BinaryTree<T> binaryTree : trees) {
if(index2 == index) {
return binaryTree;
}
index2++;
}
}
throw new Exception("其他错误!");
}
/**
* 以中序查询指定索引的节点。<br>
* 如果查询空树则抛出<code>{@link NullPointerException}</code>。<br>
* 如果输入非法索引则抛出<code>{@link ArrayIndexOutOfBoundsException}</code>。<br>
* @param index 索引
* @return 节点
* @throws Exception
* @see #isEmptyTree()
* @see #size()
* @see #getAllTreesByMidOrder()
*/
public BinaryTree<T> getNodeByMidIndex(int index) throws Exception{
if(isEmptyTree()) {
throw new NullPointerException("不能从空节点中获取指定索引的节点。");
}else if(index >= size() || index < 0) {
throw new ArrayIndexOutOfBoundsException();
}else if(index == 0) {
return this;
}else {
int index2 = 0;
List<BinaryTree<T>> trees = getAllTreesByMidOrder();
for (BinaryTree<T> binaryTree : trees) {
if(index2 == index) {
return binaryTree;
}
index2++;
}
}
throw new Exception("其他错误!");
}
/**
* 以后序查询指定索引的节点。<br>
* 如果查询空树则抛出<code>{@link NullPointerException}</code>。<br>
* 如果输入非法索引则抛出<code>{@link ArrayIndexOutOfBoundsException}</code>。<br>
* @param index 索引
* @return 节点
* @throws Exception
* @see #isEmptyTree()
* @see #size()
* @see #getAllTreesByAftOrder()
*/
public BinaryTree<T> getNodeByAftIndex(int index) throws Exception{
if(isEmptyTree()) {
throw new NullPointerException("不能从空节点中获取指定索引的节点。");
}else if(index >= size() || index < 0) {
throw new ArrayIndexOutOfBoundsException();
}else if(index == 0) {
return this;
}else {
int index2 = 0;
List<BinaryTree<T>> trees = getAllTreesByAftOrder();
for (BinaryTree<T> binaryTree : trees) {
if(index2 == index) {
return binaryTree;
}
index2++;
}
}
throw new Exception("其他错误!");
}
/**
* 获取节点总数。
* @return 总节点数。
*/
public int size() {
int size = 0;
if(!isEmptyTree()) {
size++;
if(lchild != null)
size += lchild.size();
if(rchild != null)
size += rchild.size();
}
return size;
}
/**
* 判断树是否为空。
* @return 是否为空树
* @see #data
* @see #lchild
* @see #rchild
*/
public boolean isEmptyTree() {
return data == null && lchild == null && rchild == null;
}
/**
* 判断是否为叶子节点。
* @return 是否为叶子节点
* @see #isEmptyTree()
* @see #getNodeDegree()
*/
public boolean isLeaf() {
return !isEmptyTree() && getNodeDegree() == 0;
}
/**
* 树的高度。
* @return 树的高度
* @see #lchild
* @see #rchild
* @see #isEmptyTree()
*/
public int height() {
int height = 0;
int lheight = 0;
int rheight = 0;
if(!isEmptyTree()) {
height++;
}
if(lchild != null) {
lheight += lchild.height();
}
if(rchild != null) {
rheight += rchild.height();
}
if(lheight > rheight) {
height += lheight;
}else {
height += rheight;
}
return height;
}
/**
* 检测树中是否有该节点。
* @param subTree 受检节点
* @return 是否存在
* @see #lchild
* @see #rchild
*/
public boolean isSubTreeExists(BinaryTree<T> subTree) {
boolean flag = false;
if(subTree == this) {
return true;
}else if(lchild == subTree || rchild == subTree) {
return true;
}else {
if(lchild != null)
flag = lchild.isSubTreeExists(subTree);
if(!flag) {
if(rchild != null)
flag = rchild.isSubTreeExists(subTree);
}
}
return flag;
}
/**
* 查询整棵树中是否有该节点。
* @param tree 受检节点
* @return FLAG
* @see #isSubTreeExists(Tree)
* @see #parent
*/
public boolean isNodeExistsInGlobalTree(BinaryTree<T> tree) {
if(parent == null) {
return isSubTreeExists(tree);
}else if(tree == this) {
return true;
}else {
return parent.isNodeExistsInGlobalTree(tree);
}
}
/**
* 以国内教学标准判断是否是满二叉树。<br>
* 如果是空树则抛出<code>{@link NullPointerException}</code>。
* @return 是否是满二叉树
* @see #isEmptyTree()
* @see #isLeaf()
* @see #getNodeDegree()
* @see #height()
*/
public boolean isFullTree() {
boolean isFullTree = true;
if(isEmptyTree()) {
throw new NullPointerException("不要判断一颗空树。");
}
if(parent == null && isLeaf()) {
isFullTree = false;
}else if(height() == 2 && getNodeDegree() == 2){
isFullTree = true;
}else if((lchild == null || rchild == null)){
if(!isLeaf())
isFullTree = false;
}else if(lchild.height() < height() - 1 || rchild.height() < height() - 1) {
isFullTree = false;
}else if(getNodeDegree() == 2) {
isFullTree = lchild.isFullTree();
if(isFullTree)
isFullTree = rchild.isFullTree();
}else {
isFullTree = false;
}
return isFullTree;
}
/**
* 增加左孩子节点。<br>
* 如果已有左孩子节点则抛出<code>{@link Exception}</code>。<br>
* 如果参数是空树则抛出<code>{@link NullPointerException}</code>。<br>
* 如果这棵树是空树或子节点是空树将抛出<code>{@link NullPointerException}</code>。<br>
* 如果将存在的节点插入到树中将抛出<code>{@link IllegalArgumentException}</code>。
* 要添加的节点
* @param lchild
* @return FLAG
* @throws Exception
* @see #lchild
* @see #isEmptyTree()
*/
public int setLeftChild(BinaryTree<T> lchild) throws Exception {
if(lchild.isEmptyTree()) {
throw new Exception("不能添加空树为节点。");
}else if(lchild.isEmptyTree()){
throw new NullPointerException("不能增加空树为子节点!");
}else if(isNodeExistsInGlobalTree(lchild)){
throw new IllegalArgumentException("不能增加已存在的节点!");
}else if(this.lchild == null) {
this.lchild = lchild;
lchild.setParent(this);
}else {
throw new Exception("左孩子节点已存在。");
}
return 1;
}
/**
* 判断是否为完全二叉树。<br>
* 如果是空树则抛出<code>{@link NullPointerException}</code>。
* @return 是否为完全二叉树
* @see #isEmptyTree()
* @see #isLeaf()
* @see #height()
*/
public boolean isCompleteBinaryTree() {
boolean isCompleteBinaryTree = true;
if(isEmptyTree()) {
throw new NullPointerException("不要判断一颗空树。");
}
if(lchild != null && lchild.height() >= height() - 1) {
if(height() == 2) {
isCompleteBinaryTree = true;
}else if(rchild != null && rchild.height() >= height() - 2) {
if(lchild.isLeaf()) {
isCompleteBinaryTree = true;
}else {
isCompleteBinaryTree = lchild.isCompleteBinaryTree();
}
if(rchild.isLeaf()) {
isCompleteBinaryTree = true;
}else {
isCompleteBinaryTree = rchild.isCompleteBinaryTree();
}
}else {
isCompleteBinaryTree = false;
}
}else {
isCompleteBinaryTree = false;
}
return isCompleteBinaryTree;
}
/**
* 增加右孩子节点。<br>
* 如果已有右孩子节点则抛出<code>{@link Exception}</code>。<br>
* 如果参数是空树则抛出<code>{@link NullPointerException}</code>。<br>
* 如果这棵树是空树或子节点是空树将抛出<code>{@link NullPointerException}</code>。<br>
* 如果将存在的节点插入到树中将抛出<code>{@link IllegalArgumentException}</code>。
* @param rchild 要添加的节点
* @return FLAG
* @throws Exception
* @see #rchild
* @see #isEmptyTree()
*/
public int setRightChild(BinaryTree<T> rchild) throws Exception {
if(rchild.isEmptyTree()) {
throw new NullPointerException("不能添加空树为节点。");
}else if(rchild.isEmptyTree()){
throw new NullPointerException("不能增加空树为子节点!");
}else if(isNodeExistsInGlobalTree(rchild)){
throw new IllegalArgumentException("不能增加已存在的节点!");
}else if(this.rchild == null) {
this.rchild = rchild;
rchild.setParent(this);
}else {
throw new Exception("右孩子节点已存在。");
}
return 1;
}
/**
* 删除所有子节点。<br>
* 若是空树则抛出<code>{@link NullPointerException}</code>。
* @return FLAG
* @see #isEmptyTree()
*/
public int removeAllChilds() {
if(isEmptyTree()) {
throw new NullPointerException("不能删除空树的子节点。");
}
if(lchild != null) {
lchild.clear();
lchild.destroy();
lchild = null;
}
if(rchild != null) {
rchild.clear();
rchild.destroy();
rchild = null;
}
return 1;
}
/**
* 删除左孩子节点。<br>
* 若是空树则抛出<code>{@link NullPointerException}</code>。
* @return FLAG
* @see #isEmptyTree()
*/
public int removeLeftChild() {
if(isEmptyTree()) {
throw new NullPointerException("不能删除空树的子节点。");
}
if(lchild != null) {
lchild.clear();
lchild.destroy();
lchild = null;
}
return 1;
}
/**
* 删除右孩子节点。<br>
* 若是空树则抛出<code>{@link NullPointerException}</code>。
* @return FLAG
* @see #isEmptyTree()
*/
public int removeRightChild() {
if(isEmptyTree()) {
throw new NullPointerException("不能删除空树的子节点。");
}
if(rchild != null) {
rchild.clear();
rchild.destroy();
rchild = null;
}
return 1;
}
/**
* 删除指定节点。<br>
* 如果节点不存在于该树中则抛出<code>NullPointerException</code>。
* @param node 被删除节点
* @return FLAG
* @see #isSubTreeExists(BinaryTree)
*/
public int removeNode(BinaryTree<T> node) {
if(isSubTreeExists(node)) {
if(this == node) {
clear();
destroy();
}else if(lchild == node)
removeLeftChild();
else if(rchild == node) {
removeRightChild();
}else {
if(lchild != null && lchild.isSubTreeExists(node))
lchild.removeNode(node);
else if(rchild != null && rchild.isSubTreeExists(node)){
rchild.removeNode(node);
}
}
}else {
throw new NullPointerException("该树中无此节点。");
}
return 1;
}
/**
* 以先序删除指定索引的节点。
* @param index 指定索引
* @return FLAG
* @throws Exception
* @see #getNodeByPreIndex(int)
*/
public int removeNodeByPreIndex(int index) throws Exception {
return removeNode(getNodeByPreIndex(index));
}
/**
* 以中序删除指定索引的节点。
* @param index 指定索引
* @return FLAG
* @throws Exception
* @see #getNodeByMidIndex(int)
*/
public int removeNodeByMidIndex(int index) throws Exception {
return removeNode(getNodeByMidIndex(index));
}
/**
* 以后序删除指定索引的节点。
* @param index 指定索引
* @return FLAG
* @throws Exception
* @see #getNodeByAftIndex(int)
*/
public int removeNodeByAftIndex(int index) throws Exception {
return removeNode(getNodeByAftIndex(index));
}
/**
* 从左到右,先序遍历,将数据存储在List中。<br>
* @param datas 数据表
* @see #data
* @see #lchild
* @see #rchild
*/
private void visitAllDataOfTreeByPreOrder(List<T> datas){
datas.add(data);
if(lchild != null)
lchild.visitAllDataOfTreeByPreOrder(datas);
if(rchild != null)
rchild.visitAllDataOfTreeByPreOrder(datas);
}
/**
* 从左到右,先序遍历,将数据存储在List中。<br>
* 遍历空树会抛出<code>{@link NullPointerException}</code>。
* @return 数据表
* @see #visitAllDataOfTreeByPreOrder(List)
*/
public List<T> getAllDataOfTreeByPreOrder(){
if(isEmptyTree())
throw new NullPointerException("无法遍历空树。");
List<T> datas = new ArrayList<T>();
visitAllDataOfTreeByPreOrder(datas);
return datas;
}
/**
* 从左到右,中序遍历,将数据存储在List中。<br>
* @param datas 数据表
* @see #data
* @see #lchild
* @see #rchild
*/
private void visitAllDataOfTreeByMidOrder(List<T> datas){
if(lchild != null)
lchild.visitAllDataOfTreeByMidOrder(datas);
datas.add(data);
if(rchild != null)
rchild.visitAllDataOfTreeByMidOrder(datas);
}
/**
* 从左到右,中序遍历,将数据存储在List中。<br>
* 遍历空树会抛出<code>{@link NullPointerException}</code>。
* @return 数据表
* @see #visitAllDataOfTreeByMidOrder(List)
*/
public List<T> getAllDataOfTreeByMidOrder(){
if(isEmptyTree())
throw new NullPointerException("无法遍历空树。");
List<T> datas = new ArrayList<T>();
visitAllDataOfTreeByMidOrder(datas);
return datas;
}
/**
* 从左到右,后序遍历,将数据存储在List中。<br>
* @param datas 数据表
* @see #data
* @see #lchild
* @see #rchild
*/
public void visitAllDataOfTreeByAftOrder(List<T> datas) {
if(lchild != null)
lchild.visitAllDataOfTreeByAftOrder(datas);
if(rchild != null)
rchild.visitAllDataOfTreeByAftOrder(datas);
datas.add(data);
}
/**
* 从左到右,后序遍历,将数据存储在List中。<br>
* 遍历空树会抛出<code>{@link NullPointerException}</code>。
* @return 数据表
* @see #visitAllDataOfTreeByAftOrder(List)
*/
public List<T> getAllDataOfTreeByAftOrder(){
if(isEmptyTree())
throw new NullPointerException("无法遍历空树。");
List<T> datas = new ArrayList<T>();
visitAllDataOfTreeByAftOrder(datas);
return datas;
}
/**
* 从左到右,先序遍历,将树存储在List中。
* @param trees 树表
* @see #data
* @see #lchild
* @see #rchild
*/
private void visitAllTreesByPreOrder(List<BinaryTree<T>> trees){
trees.add(this);
if(lchild != null)
lchild.visitAllTreesByPreOrder(trees);
if(rchild != null){
rchild.visitAllTreesByPreOrder(trees);
}
}
/**
* 从左到右,先序遍历,将树存储在List中。<br>
* 遍历空树会抛出<code>{@link NullPointerException}</code>。
* @return 树表
* @see #visitAllTreesByPreOrder(List)
*/
public List<BinaryTree<T>> getAllTreesByPreOrder() {
if(isEmptyTree())
throw new NullPointerException("无法遍历空树。");
List<BinaryTree<T>> trees = new ArrayList<BinaryTree<T>>();
visitAllTreesByPreOrder(trees);
return trees;
}
/**
* 从左到右,中序遍历,将树存储在List中。
* @param trees 树表
* @see #data
* @see #lchild
* @see #rchild
*/
private void visitAllTreesByMidOrder(List<BinaryTree<T>> trees) {
if(lchild != null)
lchild.visitAllTreesByMidOrder(trees);
trees.add(this);
if(rchild != null)
rchild.visitAllTreesByMidOrder(trees);
}
/**
* 从左到右,中序遍历,将树存储在List中。<br>
* 遍历空树会抛出<code>{@link NullPointerException}</code>。
* @return 树表
* @see #visitAllTreesByMidOrder(List)
*/
public List<BinaryTree<T>> getAllTreesByMidOrder(){
if(isEmptyTree())
throw new NullPointerException("无法遍历空树。");
List<BinaryTree<T>> trees = new ArrayList<BinaryTree<T>>();
visitAllTreesByMidOrder(trees);
return trees;
}
/**
* 从左到右,后序遍历,将树存储在List中。
* @param trees 树表
* @see #data
* @see #lchild
* @see #rchild
*/
private void visitAllTreesByAftOrder(List<BinaryTree<T>> trees) {
if(lchild != null)
lchild.visitAllTreesByAftOrder(trees);
if(rchild != null)
rchild.visitAllTreesByAftOrder(trees);
trees.add(this);
}
/**
* 从左到右,后序遍历,将树存储在List中。<br>
* 遍历空树会抛出<code>{@link NullPointerException}</code>。
* @return 树表
* @see #visitAllTreesByAftOrder(List)
*/
public List<BinaryTree<T>> getAllTreesByAftOrder(){
if(isEmptyTree())
throw new NullPointerException("无法遍历空树。");
List<BinaryTree<T>> trees = new ArrayList<BinaryTree<T>>();
visitAllTreesByAftOrder(trees);
return trees;
}
/**
* 置空树。
* @see #isLeaf()
*/
public void clear() {
data = null;
parent = null;
if(!isLeaf()) {
if(lchild != null) {
lchild.clear();
lchild.destroy();
lchild = null;
}
if(rchild != null) {
rchild.clear();
rchild.destroy();
rchild = null;
}
}
}
/**
* 销毁一棵空树。
* @see #isEmptyTree()
*/
@Override
public void destroy() {
if(isEmptyTree()) {
parent = null;
try {
super.finalize();
System.out.println("砍树。");
}catch(Throwable e) {
System.out.println("对象无需销毁。");
}
}else {
try {
throw new Exception("无法销毁非空树!");
} catch (Exception e) {
e.printStackTrace();
}
}
}
}