二叉树先序,中序,后序遍历
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二叉树先序,中序,后序遍历相关的知识,希望对你有一定的参考价值。
二叉树实现如下:
1 public class BinaryTree<T> { 2 private T data; 3 private BinaryTree<T> left; 4 private BinaryTree<T> right; 5 6 private BinaryTree(T data) { 7 this.data = data; 8 } 9 public BinaryTree() { 10 11 } 12 }
先序遍历递归实现:
1.访问根节点;
2.先序遍历左子树;
3.先序遍历右子树;
1 public void preOrderRecur(BinaryTree head) { 2 if(head == null) { 3 return ; 4 }else { 5 System.out.println(head.data + " "); 6 preOrderRecur(head.left); 7 preOrderRecur(head.right); 8 } 9 }
先序遍历非递归实现:
1.首先申请一个新的栈,记为stack;
2.将头结点head压入stack中;
3.每次从stack中弹出栈顶节点,记为cur,然后打印cur值,如果cur右孩子不为空,则将右孩子压入栈中;如果cur的左孩子不为空,将其压入stack中;
4.重复步骤3,直到stack为空.
1 public void preOrder(BinaryTree head) { 2 if(head == null) { 3 return ; 4 }else { 5 Stack<BinaryTree> stack = new Stack<BinaryTree>(); 6 stack.push(head); 7 while(!stack.isEmpty()) { 8 BinaryTree cur = stack.pop(); 9 System.out.print(cur.data + " "); 10 if(cur.right != null) { 11 stack.push(cur.right); 12 } 13 if(cur.left != null) { 14 stack.push(cur.left); 15 } 16 } 17 } 18 }
中序遍历递归实现:
1.中序遍历左子树;
2.访问根节点;
3.中序遍历右子树;
1 public void inOrderRecur(BinaryTree head) { 2 if(head == null) { 3 return ; 4 }else { 5 inOrderRecur(head.left); 6 System.out.print(head.data + " "); 7 inOrderRecur(head.right); 8 } 9 }
中序遍历非递归实现:
1.申请一个新栈,记为stack,申请一个变量cur,初始时令cur为头节点;
2.先把cur节点压入栈中,对以cur节点为头的整棵子树来说,依次把整棵树的左子树压入栈中,即不断令cur=cur.left,然后重复步骤2;
3.不断重复步骤2,直到发现cur为空,此时从stack中弹出一个节点记为node,打印node的值,并让cur = node.right,然后继续重复步骤2;
4.当stack为空并且cur为空时结束.
1 public void inOrder(BinaryTree head) { 2 if(head == null) { 3 return ; 4 }else { 5 Stack stack = new Stack(); 6 BinaryTree cur = head; 7 while(!stack.isEmpty() || cur != null) { 8 while(cur != null) { 9 stack.push(cur); 10 cur = cur.left; 11 } 12 BinaryTree node = (BinaryTree) stack.pop(); 13 System.out.print(node.data + " "); 14 cur = node.right; 15 } 16 } 17 18 }
后序遍历递归实现:
1.后序遍历左子树;
2.后序遍历右子树;
3.访问根节点;
1 public void posOrderRecur(BinaryTree head) { 2 if(head == null) { 3 return ; 4 }else { 5 posOrderRecur(head.left); 6 posOrderRecur(head.right); 7 System.out.print(head.data + " "); 8 } 9 }
后序遍历非递归实现:
方法一:使用两个栈实现
1.申请两个栈s1,s2,然后将头结点压入s1中;
2.从s1中弹出的节点记为cur,然后先把cur的左孩子压入s1中,再把cur的右孩子压入s1中;
3.在整个过程中,每一个从s1中弹出的节点都放在第二个栈s2中;
4.不断重复步骤2和步骤3,直到s1为空,过程停止;
5.从s2中依次弹出节点并打印,打印的顺序就是后序遍历的顺序;
1 public static void posOrder1(BinaryTree head) { 2 if(head == null) { 3 return ; 4 }else { 5 Stack s1 = new Stack(); 6 Stack s2 = new Stack(); 7 s1.push(head); 8 BinaryTree cur = new BinaryTree(); 9 cur = head; 10 while(!s1.isEmpty()) { 11 cur =(BinaryTree) s1.pop(); 12 if (cur.left != null) { 13 s1.push(cur.left); 14 } 15 if (cur.right != null) { 16 s1.push(cur.right); 17 } 18 s2.push(cur); 19 } 20 while(!s2.isEmpty()) { 21 BinaryTree r = (BinaryTree) s2.pop(); 22 System.out.print(r.data + " "); 23 } 24 } 25 }
方法二:使用一个栈
1.申请一个栈stack,将头节点压入stack,同时设置两个变量 h 和 c,在整个流程中,h代表最近一次弹出并打印的节点,c代表当前stack的栈顶节点,初始时令h为头节点,,c为null;
2.每次令c等于当前stack的栈顶节点,但是不从stack中弹出节点,此时分一下三种情况:
(1)如果c的左孩子不为空,并且h不等于c的左孩子,也不等于c的右孩子,则吧c的左孩子压入stack中
(2)如果情况1不成立,并且c的右孩子不为空,并且h不等于c的右孩子,则把c的右孩子压入stack中;
(3)如果情况1和2不成立,则从stack中弹出c并打印,然后令h等于c;
3.一直重复步骤2,直到stack为空.
1 public static void posOrder2(BinaryTree head) { 2 if(head == null) 3 return ; 4 else { 5 Stack stack = new Stack(); 6 stack.push(head); 7 BinaryTree h = head; 8 BinaryTree c = null; 9 while(!stack.isEmpty()) { 10 c = (BinaryTree) stack.peek(); 11 if(c.left != null & h != c.left & h != c.right) 12 stack.push(c.left); 13 else if(c.right != null & h != c.right) 14 stack.push(c.right); 15 else { 16 BinaryTree r = new BinaryTree(); 17 r = (BinaryTree) stack.pop(); 18 System.out.print(r.data + " "); 19 h = c; 20 } 21 } 22 } 23 }
以上是关于二叉树先序,中序,后序遍历的主要内容,如果未能解决你的问题,请参考以下文章