二叉树详解
来源:互联网 发布:淘宝网首页烤面筋 编辑:程序博客网 时间:2024/06/16 21:23
1、二叉树定义
计算机中数据结构的一种,计算机中数据结构的一种每个节点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用于实现二叉查找树和二叉堆。
完全二叉树:只有最下面的两层结点度能够小于2,并且最下面一层的结点都集中在该层最左边的若干位置的二叉树
满二叉树:除最后一层无任何子节点外,每一层上的所有结点都有两个子结点二叉树。
2、相关术语定义
树的结点:包含一个数据元素及若干指向子树的分支;
孩子结点:结点的子树的根称为该结点的孩子;
双亲结点:B 结点是A 结点的孩子,则A结点是B 结点的双亲;
兄弟结点:同一双亲的孩子结点; 堂兄结点:同一层上结点;
祖先结点: 从根到该结点的所经分支上的所有结点子孙结点:以某结点为根的子树中任一结点都称为该结点的子孙
结点层:根结点的层定义为1;根的孩子为第二层结点,依此类推;
树的深度:树中最大的结点层
结点的度:结点子树的个数
树的度: 树中最大的结点度。
叶子结点:也叫终端结点,是度为 0 的结点;
分枝结点:度不为0的结点;
3、二叉树性质
(1) 在非空二叉树中,第i层的结点总数不超过 , i>=1;
(2) 深度为h的二叉树最多有 个结点(h>=1),最少有h个结点;
(3) 对于任意一棵二叉树,如果其叶结点数为N0,而度数为2的结点总数为N2,则N0=N2+1;
(4) 具有n个结点的完全二叉树的深度为
(5)有N个结点的完全二叉树各结点如果用顺序方式存储,则结点之间有如下关系:
若I为结点编号则 如果I>1,则其父结点的编号为I/2;
如果2*I<=N,则其左儿子(即左子树的根结点)的编号为2*I;若2*I>N,则无左儿子;
如果2*I+1<=N,则其右儿子的结点编号为2*I+1;若2*I+1>N,则无右儿子。
(6)给定N个节点,能构成h(N)种不同的二叉树。
h(N)为卡特兰数的第N项。h(n)=C(2*n,n)/(n+1)。
(7)设有i个枝点,I为所有枝点的道路长度总和,J为叶的道路长度总和J=I+2i
4、三种遍历顺序
先序遍历
首先访问根,再先序遍历左(右)子树,最后先序遍历右(左)子树
中序遍历
首先中序遍历左(右)子树,再访问根,最后中序遍历右(左)子树
后序遍历
首先后序遍历左(右)子树,再后序遍历右(左)子树,最后访问根
5、根据其中两种遍历方式重建二叉树,java代码实现
5.1 已知前序和中序遍历,用java重建二叉树
方法一
package com.jason.algorithm;import java.util.HashMap;public class Solution {public static void main(String[] args) {int pre[] = { 1, 2, 4, 7, 3, 5, 6, 8 };int in[] = { 4, 7, 2, 1, 5, 3, 8, 6 };Solution solution = new Solution();solution.reConstructBinaryTree(pre, in);}public TreeNode reConstructBinaryTree(int[] pre, int[] in) {if (pre == null || in == null) {return null;}HashMap<Integer, Integer> hashMap = new HashMap<Integer, Integer>();for (int i = 0; i < in.length; i++) {hashMap.put(in[i], i);}return preIn(pre, 0, pre.length - 1, in, 0, in.length - 1, hashMap);}// {1,2,4,7,3,5,6,8} pre 根左右// {4,7,2,1,5,3,8,6} in 左根右// {7,4,2,5,8,6,3,1} end// 1// 2 3// 4 5 6// 7 8// 根据前序和中序还原二叉树public TreeNode preIn(int[] p, int pi, int pj, int[] n, int ni, int nj,HashMap<Integer, Integer> map) {if (pi > pj) {return null;}TreeNode head = new TreeNode(p[pi]);int index = map.get(p[pi]);// 根据前序遍历知道根节点,根据中序遍历知道根左边的为左子树,右边的为右子树head.left = preIn(p, pi + 1, pi + index - ni, n, ni, index - 1, map);head.right = preIn(p, pi + index - ni + 1, pj, n, index + 1, nj, map);System.out.println("head =" + (head != null ? head.val : " ")+ " head.left ="+ (head.left != null ? head.left.val : " ")+ " head.right ="+ (head.right != null ? head.right.val : " "));return head;}}
方法二
public class BinaryTree {public static void main(String[] args) {int inorder[] = { 4, 7, 2, 1, 5, 3, 8, 6 };int preorder[] = { 1, 2, 4, 7, 3, 5, 6, 8 };BinaryTree binaryTree = new BinaryTree();// 利用前序和中序,创建二叉树binaryTree.buildTree(preorder, inorder);}int pInorder;int pPreorder;public TreeNode buildTree(int[] preorder, int[] inorder, TreeNode node) {if (pPreorder > 7) {return null;}TreeNode head = new TreeNode(preorder[pPreorder++]);if (inorder[pInorder] != head.val) {head.right = buildTree(preorder, inorder, head);}pInorder++;if (node == null || inorder[pInorder] != node.val) {head.left = buildTree(preorder, inorder, node);}System.out.println("head =" + (head != null ? head.val : " ")+ " head.left ="+ (head.left != null ? head.left.val : " ")+ " head.right ="+ (head.right != null ? head.right.val : " "));return head;}public TreeNode buildTree(int[] preorder, int[] inorder) {return buildTree(preorder, inorder, null);}}
TreeNode.java
package com.jason.algorithm; public class TreeNode { int val; TreeNode left; TreeNode right; TreeNode(int x) { val = x; } }
5.2 已知后序和中序遍,用java重建二叉树
public class BinaryTree {public static void main(String[] args) {int inorder[] = { 4, 7, 2, 1, 5, 3, 8, 6 };int postorder[] = { 7, 4, 2, 5, 8, 6, 3, 1 };BinaryTree binaryTree = new BinaryTree();// 利用后序和中序,创建二叉树binaryTree.buildTree(inorder, postorder);}int pInorder;int pPostorder;public TreeNode buildTree(int[] inorder, int[] postorder, TreeNode node) {if (pPostorder < 0) {return null;}TreeNode head = new TreeNode(postorder[pPostorder--]);if (inorder[pInorder] != head.val) {head.right = buildTree(inorder, postorder, head);}pInorder--;if (node == null || inorder[pInorder] != node.val) {head.left = buildTree(inorder, postorder, node);}System.out.println("head =" + (head != null ? head.val : " ")+ " head.left ="+ (head.left != null ? head.left.val : " ")+ " head.right ="+ (head.right != null ? head.right.val : " "));return head;}public TreeNode buildTree(int[] inorder, int[] postorder) {pInorder = inorder.length - 1;pPostorder = postorder.length - 1;return buildTree(inorder, postorder, null);}}
5.3 已知前序和后序求中序遍历
如果只有前序和后序遍历只能确定树的根,无法确定左子树和右子树,目前还没想到求解方法。如果你有好的实现方法,欢迎留言一起学习,谢谢!
- 二叉树详解
- 平衡二叉树 详解
- 详解平衡二叉树
- 二叉树详解
- 二叉树实现详解
- 二叉树递归详解
- 二叉查找树详解
- hdu1710 二叉树详解
- 平衡二叉树详解
- 平衡二叉树详解
- 二叉树详解
- 平衡二叉树详解
- 二叉树-详解二叉排序树
- 二叉树详解
- 二叉查找树详解
- 二叉树操作详解
- 详解二叉搜索树
- 平衡二叉树详解
- 算法训练 删除数组零元素
- opencv学习_16(CvMat矩阵结构以及矩阵数据访问)
- servlet3.0新特性——注解支持
- 数据库内连接、左连接、右连接、全连接
- Python学习笔记9-1
- 二叉树详解
- 服务器TIME_WAIT和CLOSE_WAIT详解和解决办法
- 计算机英文论文新手写作大纲
- 数据原理-函数依赖
- hdoj 4272 LianLianKan 数据太水
- 使用matlab求解二维浅水方程的数值解(一)—浅水波
- 权重云,全新的理念架构,一个直接了当快速获取权重的强大云生态——流量兄弟
- InnoDB行锁的实现分析
- MLP、RBF、SVM网络比较及其应用前景