编程之美——3.9重建二叉树和3.10分层遍历二叉树(Java and C++)
2014-09-08 12:02
567 查看
编程之美——3.9、重建二叉树 and 3.10、分层遍历二叉树
(Java and C++)
给定一个前序和中序变量的结果,写一个算法重建这棵树:如:
![](http://images.cnitblog.com/blog/277239/201308/29002209-0c323160f6cd4f1484b8eec8b9dcb247.jpg)
1、根据前序遍历结果和中序遍历结果重建二叉树:
前序: a b d c e f
中序: d b a e c f
前序遍历的每一个节点,都是当前子树的根节点,同时,以对应的节点
为边界,就会把前序遍历的结果分为左子树和右子树。
a是前序中第一个节点,以a为中界,把中序的结果分成:
左:db
右:ecf
对于db,由于在前序中b在d前面,所以,b是d的父亲。
对于ecf,前序中c在前面,c为父亲,c把e和f分开。
2、从上之下按层遍历二叉树:
Java代码:
C++:
分层遍历的另两个实现:http://www.cnblogs.com/miloyip/archive/2010/05/12/binary_tree_traversal.html
http://blog.csdn.net/luyafei_89430/article/details/12967411 http://www.cnblogs.com/youxin/p/3288261.html
(Java and C++)
给定一个前序和中序变量的结果,写一个算法重建这棵树:如:
![](http://images.cnitblog.com/blog/277239/201308/29002209-0c323160f6cd4f1484b8eec8b9dcb247.jpg)
1、根据前序遍历结果和中序遍历结果重建二叉树:
前序: a b d c e f
中序: d b a e c f
前序遍历的每一个节点,都是当前子树的根节点,同时,以对应的节点
为边界,就会把前序遍历的结果分为左子树和右子树。
a是前序中第一个节点,以a为中界,把中序的结果分成:
左:db
右:ecf
对于db,由于在前序中b在d前面,所以,b是d的父亲。
对于ecf,前序中c在前面,c为父亲,c把e和f分开。
2、从上之下按层遍历二叉树:
Java代码:
import java.util.LinkedList; import java.util.Queue; import java.util.Vector; public class Main { static Main instance =new Main(); public static void main(String[] arg){ char[] preOrder={'a','b','d','c','e','f'}; char[] inOrder ={'d','b','a','e','c','f'}; Node root = buildTree(preOrder,inOrder,0,0,preOrder.length,null); preOrderTraversal(root); System.out.println("\n==============================="); inOrderTraversal(root); System.out.println("\n==============================="); traversalAtLevel(root, 2); System.out.println("\n==============================="); TraversalByLevel(root, 3); System.out.println("\n==============================="); TraversalByLevelUnknowDeep(root); System.out.println("\n==============================="); TraversalByLevel_2(root); System.out.println("\n==============================="); System.out.println("BFS_000"); BFS_000(root); System.out.println("BFS_1"); BFS_1(root); System.out.println("BFS_2"); BFS_2(root); } public static Node buildTree(char[] preOrder,char[] inOrder ,int pPreOrder ,int pInOrder ,int treeLen ,Node root){ if(root ==null){ root = instance.new Node(preOrder[pPreOrder]);//前序遍历的第一个节点作为Root } //! 如果当前的树长度为1,那么已经是最后一个节点了 if(treeLen==1){ return root; } int pInOrder_bak =pInOrder; while(inOrder[pInOrder]!= preOrder[pPreOrder]){ pInOrder++; if(pInOrder-pInOrder_bak>treeLen){ break; } } int leftLength =pInOrder-pInOrder_bak; int rightlength =treeLen- leftLength -1; if(leftLength>0){ root.left =buildTree(preOrder,inOrder,pPreOrder+1,pInOrder_bak,leftLength,root.left); } if(rightlength>0){ root.right=buildTree(preOrder,inOrder,pPreOrder+leftLength+1,pInOrder_bak+leftLength+1,rightlength,root.right); } return root; } //前序遍历 public static void preOrderTraversal(Node node){ if(node!=null){ System.out.print(node.getVal()+" "); if(node.left!=null){ preOrderTraversal(node.left); } if(node.right != null){ preOrderTraversal(node.right); } } } //中序遍历 public static void inOrderTraversal(Node node){ if(node!=null){ if(node.left != null){ inOrderTraversal(node.left); } System.out.print(node.getVal()+" "); if(node.right !=null){ inOrderTraversal(node.right); } } } //特定层输出 public static int traversalAtLevel(Node root,int level){ //节点为空 或者 层数已经小于0,直接返回 if(root == null || level <0){ return 0; } //Level==0,说明已经减了,减了level次到达想要输出的层,输出。 //指定层才输出的判断条件 if(level == 0){ System.out.print(root.val+" "); return 1; } return traversalAtLevel(root.left , level-1) //去下一层的左孩子 +traversalAtLevel(root.right, level-1);//去下一层的右孩子 } //已经深度的层遍历 public static void TraversalByLevel(Node root ,int deep){ for(int level=0;level<deep;level++){ traversalAtLevel(root, level); if(level!=deep-1) System.out.println(); } } //未知深度的层遍历 //前提是traversalAtLevel(root, level)有返回值,以判断是否成功遍历了特定一行(行非空) public static void TraversalByLevelUnknowDeep(Node root){ boolean b=false; for(int level=0; ;level++){ if(traversalAtLevel(root, level) == 0){ b =true; break; } if(!b){ System.out.println(); } } } //不使用递归,提升效率的的层遍历 //使用vector容器来储存n个节点信息,并用一个游标变量last记录前一层的访问结束条 public static void TraversalByLevel_2(Node root){ if(root == null){ return ; } Vector<Node> vc =new Vector<Node>(); vc.add(root); int last =vc.size(); int cur =0; while(cur<vc.size()){ last =vc.size(); while(cur < last){ System.out.print(vc.get(cur).val+" "); if(vc.get(cur).left != null){ vc.add(vc.get(cur).left); } if(vc.get(cur).right != null){ vc.add(vc.get(cur).right); } cur++; } System.out.println(); } } //使用Queue将二叉树按层顺序加入到队列中,再出队,这里没有换行,关键是如何换行输出 public static void BFS_000(Node root){ queue1.clear(); if(root == null){ return ; } queue1.add(root); while (!queue1.isEmpty()){ if(queue1.peek().left !=null){ queue1.add(queue1.peek().left); } if(queue1.peek().right != null){ queue1.add(queue1.peek().right); } System.out.print(queue1.poll().val+" "); } } static Queue<Node> queue1 =new LinkedList<Node>(); static Queue<Node> queue2 =new LinkedList<Node>(); //两个Queue来实现换行,queue1存放当前输出行,queue2存放下一行 public static void BFS_1(Node root){ queue1.clear(); queue2.clear(); if(root == null){ return ; } queue1.add(root); while (!queue1.isEmpty()){ if(queue1.peek().left !=null){ queue2.add(queue1.peek().left); } if(queue1.peek().right != null){ queue2.add(queue1.peek().right); } System.out.print(queue1.poll().val+" "); if(queue1.isEmpty()){ System.out.println(); while(!queue2.isEmpty()){ queue1.add(queue2.poll()); } } } } //类比使用cur,在每行结束的时候加一个标记节点‘@’ public static void BFS_2(Node root){ if(root == null){ return ; } queue1.clear(); queue1.add(root); Node changLine =instance.new Node('@'); queue1.add(changLine); while(queue1.peek()!= changLine){ if( queue1.peek().left!= null){ queue1.add(queue1.peek().left); } if( queue1.peek().right !=null){ queue1.add(queue1.peek().right); } System.out.print(queue1.poll().val+" "); if(queue1.peek() ==changLine){ queue1.poll(); System.out.println(); queue1.add(changLine); } } } class Node{ char val; Node left; Node right; public Node(char c){ val =c; left =null; right=null; } public char getVal() { return val; } public void setVal(char val) { this.val = val; } } }
C++:
分层遍历的另两个实现:http://www.cnblogs.com/miloyip/archive/2010/05/12/binary_tree_traversal.html
http://blog.csdn.net/luyafei_89430/article/details/12967411 http://www.cnblogs.com/youxin/p/3288261.html
相关文章推荐
- 分层遍历二叉树(编程之美3.10)
- 编程之美:第三章 结构之法 3.10分层遍历二叉树
- 《编程之美》3.10分层遍历二叉树
- 《编程之美》 3.10 分层遍历二叉树
- 编程之美——3.10 分层遍历二叉树
- 编程之美3.10 分层遍历二叉树
- 《编程之美》读书笔记16: 3.10 分层遍历二叉树
- 重建二叉树_《编程之美》3.9
- 编程之美系列之二叉树的分层遍历
- 《编程之美》:分层遍历二叉树
- 二叉树的遍历(Java,前序、中序、后序、递归and非递归)
- 3.10 分层遍历二叉树 扩展问题一、二
- 根据前序遍历和中序遍历重建二叉树的Java实现
- 《编程之美》3.9重建二叉树
- 编程之美-3.10-分层遍历二叉树
- 编程之美-分层遍历二叉树
- 《编程之美》读书笔记19: 3.9 重建二叉树
- 编程之美--根据遍历结果重建二叉树
- 重建二叉树(编程之美3.9)
- 编程之美---分层遍历二叉树