在看这篇博客前,一定要对二叉树的基本概念、性质以及递归有一定的了解,否则可能会。。。。
首先在这里要复习一下二叉树的概念,由于普通的二叉树和完全二叉树的创建方法不同,所以需要掌握这两种二叉树的特点和不同。
二叉树定义:
一棵二叉树是结点的一个有限集合,该集合或者为空,或者是由一个根节点加上两棵分别称为左子树和右子树的二叉树组成。
二叉树的特点:
每个结点最多有两棵子树,即二叉树不存在度大于2的结点。
二叉树的子树有左右之分,其子树的次序不能颠倒。
满二叉树:在一棵二叉树中,如果所有分支结点都存在左子树和右子树,并且所有叶子节点都在同一层上
完全二叉树:如果一棵具有N个结点的二叉树的结构与满二叉树的前N个结点的结构相同,称为完全二叉树
完全二叉树的特点:
1.叶子节点只出现在最下面两层
2.最下层的叶子一定集中在左部连续位置
3.倒数第二层若有叶子节点,一定都在右部连续位置
4.如果节点度为1,则该节点只有左孩子,即不存在只有右孩子的情况
5.同样节点数的二叉树,完全二叉树的深度最小
对于具有n个结点的完全二叉树,如果按照从上至下从左至右的顺序
对所有节点从0开始编号,则对于序号为i的结点有:
1.若i>0,双亲序号:(i-1)/2; i=0,i为根节点编号,无双亲结点
2.若2i+1<n,左孩子序号:2i+1,否则无左孩子
3.若2i+2<n,右孩子序号:2i+2, 否则无右孩子
理解完全二叉树的定义和性质,对于理解下面创建完全二叉树的程序很重要!!!
在这里还要稍稍提一下四种遍历方式:
前序遍历:先访问根节点,再前序遍历根节点的左子树,最后前序遍历根节点的右子树。(根–左--右,访问某一个节点其实就是把它的值打印出来)
中序遍历:中序遍历根节点的左子树,访问根节点,中序遍历右子。(左–根--右)
后序遍历:后序遍历根节点的左子树,后序遍历根节点的右子树,访问根节点。(左–右--根)
层序遍历:按照从上到下,从左到右的方式一层一层的访问每个节点。
下面是节点的定义:
class TreeNode{
char val;
TreeNode left;
TreeNode right;
public TreeNode(char val){
this.val=val;
this.left=null;
this.right=null;
}
public TreeNode(){
}
}
下面是普通二叉树的创建:
利用先序遍历后的结果递归实现,先序遍历中,左孩子或右孩子为null用#代替
//按照先序遍历的方法创建二叉树,首先要将先序遍历结果存放在数组arr中
//数组arr关系到创建出来的二叉树的正确性
//如果arr中存放不是某棵二叉树先序遍历的结果,那么程序就会出现错误
public void createBinaryTree(char[] arr){
if(arr == null || arr.length < 3){
return ;
}
this.root = new TreeNode();
_createBinaryTree(this.getRoot(),arr,0);
}
//index用来表示数组arr的下标
public int _createBinaryTree(TreeNod