1.引言
前面寫了下。二叉樹的遞歸遍歷發(fā),但是自己寫非遞歸遍歷的時候,真是艱難。寫不出來,自己還是太水了,太水了。無奈把人家的代碼看了下。跑了下,自己在紙上走了一下。還是在此記錄下,供以后翻閱。
2.正題
先說下:非遞歸遍歷二叉樹。需要一個棧來保存根節(jié)點。然后涉及到倆個while循環(huán)。第一個while(!statck.empty()||rootNode!=null)。第二個while主要是將左子樹的節(jié)點添加進棧中,所以循環(huán)的條件while(rootNode!=null)。。接下來就是正題。
聲明節(jié)點:
public static class Node{
private int number;
private Node leftNode;
private Node rightNode;
public Node getLeftNode() {
return leftNode;
}
public Node(int number) {
this.number = number;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public void setLeftNode(Node leftNode) {
this.leftNode = leftNode;
}
public Node getRightNode() {
return rightNode;
}
public void setRightNode(Node rightNode) {
this.rightNode = rightNode;
}
}
建立二叉樹:
public static void main(String args[]){
BinTree binaryTree=new BinTree();
List<Node> treeNodes=new ArrayList<>();
treeNodes.add(new Node(6));
treeNodes.add(new Node(3));
treeNodes.add(new Node(7));
treeNodes.add(new Node(1));
treeNodes.add(new Node(4));
treeNodes.add(new Node(9));
treeNodes.forEach(treeNode -> {binaryTree.buildTree(treeNode,binaryTree.rootNode);});
// binaryTree.postorderTraversal(binaryTree.rootNode);
}
前序遍歷:
public void preorderTraversal(Node rootNode){
if (rootNode==null)
return;
Stack<Node>stack=new Stack<>();//棧,先進先出
while(rootNode!=null ||!stack.empty()){
while (rootNode!=null){
System.out.println(rootNode.getNumber());
stack.add(rootNode);
rootNode=rootNode.getLeftNode();
}
if (!stack.empty()){
Node node=stack.pop();
rootNode=node.getRightNode();
}
}
}
中序遍歷:
和前序的區(qū)別是:System的位置不同。
public void middleTraversal(Node rootNode){
if (rootNode==null)
return;
Stack<Node>stack=new Stack<>();
while(rootNode!=null||!stack.empty()){
while (rootNode!=null){
stack.add(rootNode);
rootNode=rootNode.getLeftNode();
}
if (!stack.empty()){
Node node=stack.pop();
System.out.print(node.getNumber());
rootNode=node.getRightNode();
}
}
}
后序遍歷:
后序遍歷又復雜了一點。根節(jié)點最后遍歷。前面的倆中遍歷。在處理右節(jié)點的時候,是直接調用pop()。彈出那個節(jié)點。但是 后序遍歷不能這樣搞。后序遍歷不清楚是:左-->根(右節(jié)點缺少)。左-->右-->根。右-->根(左節(jié)點缺失)。按照大神的博客說的是:需要一個棧來保存訪問的左節(jié)點,右節(jié)點。左節(jié)點 0進棧,右節(jié)點1進棧。
代碼如下:
public void postorderTraversal(Node rootNode){
Stack<Node>stack=new Stack<>();
Stack<Integer>stack1=new Stack<>();
while (!stack.empty()||rootNode!=null){
while (rootNode!=null){
stack.push(rootNode);
stack1.push(new Integer(0));//棧一直加0。代表加入的是左節(jié)點
rootNode=rootNode.getLeftNode();
}
//這個wihle 不明白。不過在紙上一步一步的走循環(huán)一次的確不行
while (!stack.empty() && stack1.peek()==1) {
stack1.pop();
System.out.print(stack.pop().getNumber());
}
if (!stack.empty()){
stack1.pop();
stack1.push(new Integer(1));//棧頂?shù)脑靥鎿Q成1,表示讀取的是當前根節(jié)點的右節(jié)點
Node node=stack.peek();
rootNode=node.getRightNode();
}
}
}
二叉樹的遍歷的確小難,不看任何資料,能寫出來的確是nb。目前就淺嘗而至算了,等一會真正遇到了 在好好品味下。二叉樹算法