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); //訪問根節點 } } }