二叉树的遍历
2015-09-21 19:52
190 查看
树(tree)是n个结点的有限集。n=0时表示树为空树。在任意一棵非空树中,有且只有一个结点为根结点(root),当n>1时,其余结点可以分为许多个互不相交的有限集T1、T2···,其中每一个集合本身也是一棵树,并且成为根结点的子树。
如果把上述中的很多集合换为两个集合,就成了树中一种实用价值比较高的树,成为二叉树。这样二叉树最多有两棵子树,分别是左子树和右子树。下面简单说下二叉树的一些规律:
性质一:在二叉树的第i层上至多有2的i-1次方个结点;
性质二:深度为k的二叉树至多有2的k次方减1个结点;
性质三:对于任意一棵二叉树,其叶子结点数为n0,度为2的结点数为n2,度为1的结点数为n1,则有n0=n2+1;
性质四:就有n个结点的完全二叉树的深度为对log2(n)取下限+1;
性质五:对有n个结点的完全二叉树按层序排序,则有:(1)i=1,根结点,无双亲;i>1,根节点为对i/2取下限。(2)如果存在,则i结点的左孩子为2i,右孩子为2i+1。
二叉树的遍历方法一般有四种:前序遍历、中序遍历、后序遍历、层序遍历。前三种是根据根结点在左结点和右结点之间的位置决定的,“根左右”就是前序遍历,“左根右”就是中序遍历,“左右根”就是后序遍历。而层序遍历字如其义,就是简单的从上到下,从左到右的依次遍历。层序遍历用的较少,此处不做研究。但是我们应该清楚前三种遍历方法的实现及根据前序(后序)和中序重新构建树,或者得到后序(前序)遍历的结果,下面就以上几个问题作如下实现。
结点结构:
前序遍历:
中序遍历:
后序遍历:
由前序、中序重建二叉树:
如果把上述中的很多集合换为两个集合,就成了树中一种实用价值比较高的树,成为二叉树。这样二叉树最多有两棵子树,分别是左子树和右子树。下面简单说下二叉树的一些规律:
性质一:在二叉树的第i层上至多有2的i-1次方个结点;
性质二:深度为k的二叉树至多有2的k次方减1个结点;
性质三:对于任意一棵二叉树,其叶子结点数为n0,度为2的结点数为n2,度为1的结点数为n1,则有n0=n2+1;
性质四:就有n个结点的完全二叉树的深度为对log2(n)取下限+1;
性质五:对有n个结点的完全二叉树按层序排序,则有:(1)i=1,根结点,无双亲;i>1,根节点为对i/2取下限。(2)如果存在,则i结点的左孩子为2i,右孩子为2i+1。
二叉树的遍历方法一般有四种:前序遍历、中序遍历、后序遍历、层序遍历。前三种是根据根结点在左结点和右结点之间的位置决定的,“根左右”就是前序遍历,“左根右”就是中序遍历,“左右根”就是后序遍历。而层序遍历字如其义,就是简单的从上到下,从左到右的依次遍历。层序遍历用的较少,此处不做研究。但是我们应该清楚前三种遍历方法的实现及根据前序(后序)和中序重新构建树,或者得到后序(前序)遍历的结果,下面就以上几个问题作如下实现。
结点结构:
class TreeNode { int value; TreeNode left; TreeNode right; public TreeNode(int value) { this.value = value; } public TreeNode(int value, TreeNode left, TreeNode right) { this(value); this.left = left; this.right = right; } }
前序遍历:
public void prePrint(TreeNode root) { if (root != null) { System.out.print(root.value + " "); prePrint(root.left); prePrint(root.right); } }
中序遍历:
public void midPrint(TreeNode root) { if (root != null) { midPrint(root.left); System.out.print(root.value + " "); midPrint(root.right); } }
后序遍历:
public void backPrint(TreeNode root) { if (root != null) { backPrint(root.left); backPrint(root.right); System.out.print(root.value + " "); } }
由前序、中序重建二叉树:
public TreeNode treeConstruct(int[] pre, int[] mid) { if (pre == null || mid == null || pre.length == 0 || mid.length == 0) return null; else return treeCons(pre, mid, 0, pre.length - 1, 0, mid.length - 1); } private TreeNode treeCons(int[] pre, int[] mid, int preStart, int preEnd, int midStart, int midEnd) { int rootValue = pre[preStart]; TreeNode root = new TreeNode(rootValue); if (preStart == preEnd) { if (midStart == midEnd && pre[preStart] == mid[midEnd]) return root; else throw new IllegalArgumentException( "pre[] and mid[] can't match"); } int rootIndex = midStart; while (rootIndex <= midEnd && mid[rootIndex] != rootValue) { rootIndex++; } if (rootIndex == midEnd && mid[rootIndex] != rootValue) throw new IllegalArgumentException(); int offset = rootIndex - midStart; int preLeftRight = preStart + offset; if (offset > 0) root.left = treeCons(pre, mid, preStart + 1, preLeftRight, midStart, rootIndex - 1); if (preLeftRight < preEnd - preStart) root.right = treeCons(pre, mid, preLeftRight + 1, preEnd, rootIndex + 1, midEnd); return root; }
相关文章推荐
- List 与 数组 互转
- 泡泡同学的微博跟新了,bfc和 ifc
- javascript中的运算符
- SVN 常用命令一览表
- RMAN备份保留与control_file_record_keep_time之间的关系
- Servlet的生命周期及web.xml的配置
- [noip2014]解方程 hash+秦九昭
- 几种任务调度的 Java 实现方法与比较
- 语音的情感识别问题
- Objectvie-C------NSArray、NSMutableArray基本用法总结
- usb 接口突然不能使用了怎么办?
- java环境变量配置
- Cocos3.8创建新工程,添加库工程
- 词法分析程序
- ogre嵌入MFC教程
- findbug类型
- 进程终止函数:abort, atexit, exit, _exit, _Exit http://blog.sina.com.cn/s/blog_605f5b4f0100x3v0.html
- 模拟器下调用AVAudioRecorder的prepareToRecord耗时有点久怎么办?
- SQL Server2008知识点总结
- hdu 5446(2015长春网络赛J题 Lucas定理+中国剩余定理)