一、树的基本定义:树(tree)是N(N>=0)个结点的有限集合。在任意的一棵树中<1>有且只有一个特定的根(root)节点 ;<2>当n》1时其余节点可分为m个互不相交的有限集,每个集合的本身就是一棵树。
二、二叉树的定义:它的特点是每个节点最多只有两棵子树(二叉树中不存在度大于2的节点),并且,二叉树的子树有左右之分,其次序不能任意颠倒。
三、树的一些名词的含义:<1>度:表示节点拥有的子树数;<2>叶子(终端节点):表示度为0的节点;<3>深度:树节点的最大层次称为树的深度或高度。
四、二叉树的一些性质:
1、在二叉树中的第i层上最多有 个节点 (i>=1);
2、深度为K的二叉树最多有 个节点(k>=1);
3、对于任何一棵二叉树T,如果终端节点数为a,度为2的节点数为b,则a=b+1;
4、具有n个节点的完全二叉树的深度为
5、完全二叉树、满二叉树、对树的节点从左到右遍历不会出现间断则为完全二叉树;
五、遍历二叉树:
1、先序遍历二叉树:访问根节点,先序遍历左子树,先序遍历右子树
2、中序遍历二叉树:先序遍历左子树,访问根节点,先序遍历右子树
3、后序遍历二叉树:先序遍历左子树,先序遍历右子树,访问根节点
构造一个二叉树如下:
先序遍历二叉树:-+a*b-cd/ef 中序遍历二叉树:a+b*c-d-e/f 后序遍历二叉树:abcd-*+ef/-
六、查找二叉树:使二叉树成为一棵二叉树的性质是,对于树中的每个节点x,它的左子树中所的项的值小于x中的项,而它的右子树所有的项值大于x中的值。
查找二叉树
非查找二叉树
七、使用java对查找二叉树进行操作:定义、先序遍历、中序遍历、后序遍历、得到一棵树的深度、插入一个节点、删除一个节点
先序遍历、1、java对查找二叉树节点进行定义:
public class TreeNode {
TreeNode left;//左子树
TreeNode right;//右子树
int val;//结点值
//定义两个构造函数
public TreeNode(int x) {
this(null, null, x);
}
public TreeNode(TreeNode right,TreeNode left,int value){
this.left=left;
this.right=right;
this.val=value;
}
}
2、对二叉树进行遍历:
先序遍历:
//打印一课树(先序)使用递归的方法
public void PreOrderprintTree(TreeNode root){
//先序遍历(root(结点)-->左子树-->右子树)
if(root==null){
return ;
}
System.out.print(root.val+" ");//根结点
PreOrderprintTree(root.left);//左子树
PreOrderprintTree(root.right);//右子树
}
中序遍历:
//打印一课树(中序)使用递归的方法
public void inOrderprintTree(TreeNode root){
//中序(左子树-->root(结点)-->右子树)
if(root==null){
return;
}
inOrderprintTree(root.left);//左子树
System.out.print(root.val+" ");//根结点
inOrderprintTree(root.right);//右子树
}
后序遍历:
//打印一课树(后序)使用递归的方法
public void postOrderprintTree(TreeNode root){
//后序(左子树-->右子树-->root(结点))
if(root==null){
return ;
}
postOrderprintTree(root.left);//左结点
postOrderprintTree(root.right);//右结点
System.out.print(root.val+" ");//根结点
}
3、得到一棵树的深度:
//得到一棵二叉树的深度
public int length(TreeNode root){
int depth_left;
int depth_right;
if(root == null){
return 0;
}
depth_left=length(root.left);
depth_right=length(root.right);
return depth_left>depth_right?depth_left+1:depth_right+1;
}
4、向查找二叉树中插入一个节点:
/*插入一个项*/
private TreeNode insert(int x,TreeNode t){
if(t==null){
t=new TreeNode(x,null,null);
//通过判断,插入的节点在左边还是在右边
}else if(x<t.val){
t.left=insert(x,t.left);
}else if(x>t.val){
t.right=insert(x,t.right);
}
return t;
}
5、删除一个节点:
//删除指定的项,并返回当前删除的项,递归算法
private TreeNode remove(int x,TreeNode t){
if(t==null){
return t;
}
if(x<t.val){
t.left=remove(x,t.left);
}else if(x>t.val){
t.right=remove(x,t.right);
}else if(t.left!=null&&t.right!=null){
t.val=findMin(t.right)val;
t.right=remove(x,t.right);
}else{
t=(t.left==null)?t.left:t.right;
}
return t;
}
/*找到一棵树的最小项(其实就是找到最左边的项)*/
private TreeNdoe findMin(TreeNode t){
if(t==null){
return null;
}else if(t.left==null){
return t;
}else{
return findMin(t.left);
}
}
八、AVL 树:表示树是带平衡(balance)条件的二叉查找树。这个平衡条件必须是容易保持,而且必须保证树的深度是O(logN)。最简单的方法是要求左右子树具有相同的高度;或者每个节点都必须要有相同的高度。一棵AVL树是其一个节点的左子树和右子树高度差最多为1的二叉查找树。
AVL平衡树
非AVL平衡树