public class BinaryTreeNode {
private int data;//數據
private BinaryTreeNode leftChild;//左孩子
private BinaryTreeNode rightChild;//右孩子
public int getData() {
return data;
}
public void setData(int data) {
this.data=data;
}
public BinaryTreeNode getLeftChild() {
return leftChild;
}
public void setLeftChild(BinaryTreeNode leftChirld) {
this.leftChild=leftChirld;
}
public BinaryTreeNode getRightChild() {
return rightChild;
}
public void setRightChild(BinaryTreeNode rightChild) {
this.rightChild=rightChild;
}
}
public class BinaryTree {
private BinaryTreeNode root;
public BinaryTree(BinaryTreeNode root) {
this.root=root;
}
public void setRoot(BinaryTreeNode root) {
this.root=root;
}
public BinaryTreeNode getRoot() {
return root;
}
/**
* 二叉樹的清空:
* 首先提供一個清空以某個節點為根節點的子樹的方法,既遞歸地刪除每個節點;
* 接着提供一個刪除樹的方法,直接通過第一種方法刪除到根節點即可
*/
//清除某個子樹的所有節點
public void clear(BinaryTreeNode node) {
if(node!=null) {
clear(node.getLeftChild());
clear(node.getRightChild());
node=null;//刪除節點
}
}
//清空樹
public void clear() {
clear(root);
}
//判斷二叉樹是否為空
public boolean isEmpty() {
return root==null;
}
//獲取以某節點為子樹的高度
public int heigh(BinaryTreeNode node) {
if(node==null) {
return 0;//遞歸結束,空子樹高度為0
}else {
//遞歸獲取左子樹高度
int l=heigh(node.getLeftChild());
//遞歸獲取右子樹高度
int r=heigh(node.getRightChild());
//高度應該算更高的一邊,(+1是因為要算上自身這一層)
return l>r?(l+1):(r+1);
}
}
public int heigh() {
return heigh(root);
}
/**
* 求二叉樹的節點數:
* 1.求節點數時,我們看看獲取某個節點為子樹的節點數的實現。
* 2.首先節點為空,則個數肯定為0;
* 3.如果不為空,那就算上這個節點之后繼續遞歸所有左右子樹的子節點數,
* 4.全部相加就是以所給節點為根的子樹的節點數
* 5.如果求二叉樹的節點數,則輸入根節點即可
*/
public int size(BinaryTreeNode node) {
if(node==null) {
return 0;//如果節點為空,則返回節點數為0
}else {
//計算本節點 所以要+1
//遞歸獲取左子樹節點數和右子樹節點數,最終相加
return 1+size(node.getLeftChild())+size(node.getRightChild());
}
}
//獲取二叉樹的節點數
public int size() {
return size(root);
}
//返回某節點的父親節點
//node節點在subTree子樹中的父節點
public BinaryTreeNode getParent(BinaryTreeNode subTree,BinaryTreeNode node) {
if(subTree==null) {////如果是空子樹,則沒有父節點
return null;
}
//如果子樹的根節點的左右孩子之一是待查節點,則返回子樹的根節點
if(subTree.getLeftChild()==node||subTree.getRightChild()==node) {
return subTree;
}
BinaryTreeNode parent=null;
if(getParent(subTree.getLeftChild(), node)!=null) {
parent=getParent(subTree.getLeftChild(), node);
return parent;
}else {
//遞歸左右子樹
return getParent(subTree.getRightChild(), node);
}
}
//查找node節點在二叉樹中的父節點
public BinaryTreeNode getParent(BinaryTreeNode node) {
return (root==null||root==node)?null:getParent(root,node);
}
//返回左子樹
public BinaryTreeNode getLeftTree(BinaryTreeNode node) {
return node.getLeftChild();
}
//返回右子樹
public BinaryTreeNode getRightTree(BinaryTreeNode node) {
return node.getRightChild();
}
/**
* 二叉樹的插入:
* 分兩種情況:插入某個節點的左子節點;插入某個節點的右子節點
* 值得指出的是,當這個節點本身有子節點時,這樣的插入也會覆蓋原來在這個位置上的節點。
* 另外,雖然插入的是子節點,但是子節點也可以代表一顆子樹。
* 但從這個節點來看並不知道這個節點是否有左右子樹存在,所以雖然插入的是一個節點,但有可能插入很多節點(插入的是一棵子樹)
*/
//給某個節點插入左節點
public void insertLeft(BinaryTreeNode parent,BinaryTreeNode newNode) {
parent.setLeftChild(newNode);
}
//給某個節點插入右節點
public void insertRight(BinaryTreeNode parent,BinaryTreeNode newNode) {
parent.setRightChild(newNode);
}
//先序遍歷
public void PreOrder(BinaryTreeNode node){
if(node!=null){
System.out.println(node.getData()); //先訪問根節點
PreOrder(node.getLeftChild()); //先根遍歷左子樹
PreOrder(node.getRightChild()); //先根遍歷右子樹
}
}
//中序遍歷
public void InOrder(BinaryTreeNode node){
if(node!=null){
InOrder(node.getLeftChild()); //中根遍歷左子樹
System.out.println(node); //訪問根節點
InOrder(node.getRightChild()); //中根遍歷右子樹
}
}
//后序遍歷
public void PostOrder(BinaryTreeNode node){
if(node!=null){
PostOrder(node.getLeftChild()); //后根遍歷左子樹
PostOrder(node.getRightChild()); //后根遍歷右子樹
System.out.println(node); //訪問根節點
}
}
}