JAVA實現二叉樹的前、中、後序遍歷(遞迴與非遞迴)
阿新 • • 發佈:2019-01-22
最近在面試中遇到過問到二叉樹後序遍歷非遞迴實現的方法,之前以為會遞迴的解決就OK,看來還是太心存僥倖,在下一次面試之前,特地整理一下這個問題。
首先二叉樹的結構定義,java程式碼如下:
public class Node {
private int data;
private Node leftNode;
private Node rightNode;
public Node(int data, Node leftNode, Node rightNode){
this.data = data;
this .leftNode = leftNode;
this.rightNode = rightNode;
}
public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
public Node getLeftNode() {
return leftNode;
}
public void setLeftNode (Node leftNode) {
this.leftNode = leftNode;
}
public Node getRightNode() {
return rightNode;
}
public void setRightNode(Node rightNode) {
this.rightNode = rightNode;
}
}
先是前、中、後序遍歷的遞迴實現,這個還是比較簡單的
public void theFirstTraversal(Node root) { //先序遍歷
visit(root);
if (root.getLeftNode() != null) { //使用遞迴進行遍歷左孩子
theFirstTraversal(root.getLeftNode());
}
if (root.getRightNode() != null) { //遞迴遍歷右孩子
theFirstTraversal(root.getRightNode());
}
}
public void theInOrderTraversal(Node root) { //中序遍歷
if (root.getLeftNode() != null) {
theInOrderTraversal(root.getLeftNode());
}
visit(root);
if (root.getRightNode() != null) {
theInOrderTraversal(root.getRightNode());
}
}
public void thePostOrderTraversal(Node root) { //後序遍歷
if (root.getLeftNode() != null) {
thePostOrderTraversal(root.getLeftNode());
}
if(root.getRightNode() != null) {
thePostOrderTraversal(root.getRightNode());
}
visit(root);
}
但是有些面試官會考到非遞迴實現的思路,實際上需要借用棧的輔助實現。程式碼如下:
public void theFirstTraversal_Stack(Node root) { //先序遍歷
Stack<Node> stack = new Stack<Node>();
Node node = root;
while (node != null || stack.size() > 0) { //將所有左孩子壓棧
if (node != null) { //壓棧之前先訪問
visit(node);
stack.push(node);
node = node.getLeftNode();
} else {
node = stack.pop();
node = node.getRightNode();
}
}
}
public void theInOrderTraversal_Stack(Node root) { //中序遍歷
Stack<Node> stack = new Stack<Node>();
Node node = root;
while (node != null || stack.size() > 0) {
if (node != null) {
stack.push(node); //直接壓棧
node = node.getLeftNode();
} else {
node = stack.pop(); //出棧並訪問
visit(node);
node = node.getRightNode();
}
}
}
public void thePostOrderTraversal_Stack(Node root) { //後序遍歷 雙棧
Stack<Node> stack = new Stack<Node>();
Stack<Node> output = new Stack<Node>();//構造一箇中間棧來儲存逆後序遍歷的結果
Node node = root;
while (node != null || stack.size() > 0) {
if (node != null) {
output.push(node);
stack.push(node);
node = node.getRightNode();
} else {
node = stack.pop();
node = node.getLeftNode();
}
}
System.out.println(output.size());
while (output.size() > 0) {
visit(output.pop());
}
}
/** 非遞迴實現後序遍歷 單棧法*/
protected static void iterativePostorder3(Node p) {
Stack<Node> stack = new Stack<Node>();
Node node = p, prev = p;
while (node != null || stack.size() > 0) {
while (node != null) {
stack.push(node);
node = node.getLeft();
}
if (stack.size() > 0) {
Node temp = stack.peek().getRight();
if (temp == null || temp == prev) {
node = stack.pop();
visit(node);
prev = node;
node = null;
} else {
node = temp;
}
}
}
}