Java實現二叉樹三種遍歷演算法
阿新 • • 發佈:2018-12-25
</pre><p></p><p>參考網上一些資料測試整理了一下二叉樹遍歷的Java實現程式碼。</p>二叉樹三種遍歷方式:先序遍歷、中序遍歷、後序遍歷。<p>首先定義二叉樹類:</p><p></p><pre code_snippet_id="422510" snippet_file_name="blog_20140708_2_1633299" name="code" class="java">package mm.test.tree; public class BinaryTree { char data; //根節點 BinaryTree leftChild; //左孩子 BinaryTree rightChild; //右孩子 public BinaryTree() { } public void visit() { System.out.println(this.data); } public BinaryTree(char data) { this.data = data; this.leftChild = null; this.rightChild = null; } public BinaryTree getLeftChild() { return leftChild; } public void setLeftChild(BinaryTree leftChild) { this.leftChild = leftChild; } public BinaryTree getRightChild() { return rightChild; } public void setRightChild(BinaryTree rightChild) { this.rightChild = rightChild; } public char getData() { return data; } public void setData(char data) { this.data = data; } }
先序遍歷思想:根左右。首先遍歷根節點,然後遍歷左子樹和右子樹。
package mm.test.tree; import java.util.Stack; public class VisitBinaryTree { //先序遍歷非遞迴演算法 private void preOrder(BinaryTree root) { if(root!=null) { Stack<BinaryTree> stack = new Stack<BinaryTree>(); for (BinaryTree node = root; !stack.empty() || node != null;) { //當遍歷至節點位空的時候出棧 if(node == null) { node = stack.pop(); } node.visit(); //遍歷右孩子存入棧內 if(node.getRightChild()!=null) { stack.push(node.getRightChild()); } //遍歷左子樹節點 node = node.getLeftChild(); } } } //先序遍歷遞迴演算法 public void preOrderRecursion(BinaryTree root) { if(root!=null) { root.visit(); preOrderRecursion(root.getLeftChild()); preOrderRecursion(root.getRightChild()); } } }
測試程式碼:
public static void main(String args[]) { BinaryTree node = new BinaryTree('A'); <span style="white-space:pre"> </span> BinaryTree root = node; <span style="white-space:pre"> </span> BinaryTree nodeL1; <span style="white-space:pre"> </span> BinaryTree nodeL; <span style="white-space:pre"> </span> BinaryTree nodeR; <span style="white-space:pre"> </span> node.setLeftChild(new BinaryTree('B')); <span style="white-space:pre"> </span> node.setRightChild(new BinaryTree('C')); <span style="white-space:pre"> </span> nodeL1 = node.getLeftChild(); <span style="white-space:pre"> </span> nodeL1.setLeftChild(new BinaryTree('D')); <span style="white-space:pre"> </span> nodeL1.setRightChild(new BinaryTree('E')); <span style="white-space:pre"> </span> nodeL = nodeL1.getLeftChild(); <span style="white-space:pre"> </span> nodeL.setLeftChild(new BinaryTree('F')); <span style="white-space:pre"> </span> node = node.getRightChild(); <span style="white-space:pre"> </span> node.setLeftChild(new BinaryTree('G')); <span style="white-space:pre"> </span> node.setRightChild(new BinaryTree('H')); <span style="white-space:pre"> </span> nodeR = node.getLeftChild(); <span style="white-space:pre"> </span> nodeR.setLeftChild(new BinaryTree('I')); <span style="white-space:pre"> </span> nodeR.setRightChild(new BinaryTree('J')); <span style="white-space:pre"> </span> VisitBinaryTree vt= new VisitBinaryTree(); //先序遍歷遞迴和非遞迴測試 vt.preOrder(root); vt.preOrderRecursion(root); }
中序遍歷演算法:
//中序遍歷的非遞迴演算法
public void inOrder(BinaryTree root) {
if(root!=null) {
Stack<BinaryTree> stack = new Stack<BinaryTree>();
for (BinaryTree node = root; !stack.empty() || node != null; ) {
//尋找最左的左子樹節點,並將遍歷的左節點進棧
while(node!=null) {
stack.push(node);
node = node.getLeftChild();
}
if(!stack.empty()) {
node = stack.pop(); //出棧
node.visit(); //讀取節點值
node = node.getRightChild();
}
}
}
}
//中序遍歷的遞迴演算法
public void inOrderRecursion (BinaryTree root) {
if(root!=null) {
inOrderRecursion(root.getLeftChild());
root.visit();
inOrderRecursion(root.getRightChild());
}
}
測試程式碼:public static void main(String args[]) {
BinaryTree node = new BinaryTree('A');
BinaryTree root = node;
BinaryTree nodeL1;
BinaryTree nodeL;
BinaryTree nodeR;
node.setLeftChild(new BinaryTree('B'));
node.setRightChild(new BinaryTree('C'));
nodeL1 = node.getLeftChild();
nodeL1.setLeftChild(new BinaryTree('D'));
nodeL1.setRightChild(new BinaryTree('E'));
nodeL = nodeL1.getLeftChild();
nodeL.setLeftChild(new BinaryTree('F'));
node = node.getRightChild();
node.setLeftChild(new BinaryTree('G'));
node.setRightChild(new BinaryTree('H'));
nodeR = node.getLeftChild();
nodeR.setLeftChild(new BinaryTree('I'));
nodeR.setRightChild(new BinaryTree('J'));
VisitBinaryTree vt= new VisitBinaryTree();
//中序遍歷遞迴和非遞迴測試
vt.inOrder(root);
vt.inOrderRecursion(root);
}
後序遍歷:
//後序遍歷非遞迴演算法
private void postOrder(BinaryTree root) {
if(root!=null) {
Stack<BinaryTree> stack = new Stack<BinaryTree>();
for (BinaryTree node = root; !stack.empty() || node != null;) {
while(root!=null) {
stack.push(root);
root = root.getLeftChild();
}
while(!stack.empty() && root == stack.peek().getRightChild()) {
root = stack.pop();
root.visit();
}
if (stack.empty()) {
return;
} else {
root = stack.peek().getRightChild();
}
}
}
}
//後序遍歷遞迴演算法
private void postOrderRecursion(BinaryTree root) {
if(root!=null) {
postOrderRecursion(root.getLeftChild());
postOrderRecursion(root.getRightChild());
root.visit();
}
}
測試方法:
public static void main(String args[]) {
BinaryTree node = new BinaryTree('A');
BinaryTree root = node;
BinaryTree nodeL1;
BinaryTree nodeL;
BinaryTree nodeR;
node.setLeftChild(new BinaryTree('B'));
node.setRightChild(new BinaryTree('C'));
nodeL1 = node.getLeftChild();
nodeL1.setLeftChild(new BinaryTree('D'));
nodeL1.setRightChild(new BinaryTree('E'));
nodeL = nodeL1.getLeftChild();
nodeL.setLeftChild(new BinaryTree('F'));
node = node.getRightChild();
node.setLeftChild(new BinaryTree('G'));
node.setRightChild(new BinaryTree('H'));
nodeR = node.getLeftChild();
nodeR.setLeftChild(new BinaryTree('I'));
nodeR.setRightChild(new BinaryTree('J'));
VisitBinaryTree vt= new VisitBinaryTree();
//後序遍歷遞迴和非遞迴測試
vt.postOrder(root);
vt.postOrderRecursion(root);
}