二叉树的概念
二叉树是有限个数的集合,该集合或者为空,或者有一个称为根元素以及两个不相交的,被分别称为根的左子树和右子树的二叉树组成。
相关概念:
深度:树中结点的最大层数称为树的深度。
结点的度:结点所拥有的子树的个数称为该结点的度。
叶节点:度=0的节点。
满二叉树:一个二叉树的每一层结点个数都达到了最大,即为满二叉树。
树的度:树中各结点的最大值。
完全二叉树
一颗深度为k的有n个结点的二叉树,对其结点按从上自下,从左到右的顺序进行编号,如果编号i(1<=i<=n)的结点和满二叉树中编号为i的结点在二叉树中的位置相同,就称为完全二叉树。
如下:
二叉树的主要性质:
1.一颗非空二叉树的第i层上最多有2^(i-1)个结点。
2.一颗深度为k的二叉树中,最多具有2^(k-1)个结点。
3.一颗非空二叉树,如果叶子结点数为n,度数为2的结点数为x,则有:n=x+1;
4.具有n个结点的完全二叉树的深度为(log2n)+1。(2在下方)
二叉树的遍历:
二叉树的遍历分为三种:
先序遍历,中序遍历,后序遍历
先序遍历: (根左右)
前序遍历首先访问根结点然后遍历左子树,最后遍历右子树。在遍历左、右子树时,仍然先访问根结点,然后遍历左子树,最后遍历右子树。
若二叉树为空则结束返回,否则:
(1)访问根结点。
(2)前序遍历左子树。
(3)前序遍历右子树 。
中序遍历:(左根右)
中序遍历首先遍历左子树,然后访问根结点,最后遍历右子树。在遍历左、右子树时,仍然先遍历左子树,再访问根结点,最后遍历右子树。即:
若二叉树为空则结束返回
否则:
(1)中序遍历左子树。
(2)访问根结点。
(3)中序遍历右子树。
后序遍历:
后序遍历首先遍历左子树,然后遍历右子树,最后访问根结点,在遍历左、右子树时,仍然先遍历左子树,然后遍历右子树,最后遍历根结点。即:
若二叉树为空则结束返回
否则:
(1)后序遍历左子树
(2)后序遍历右子树
(3)访问根结点
例子,给定一个二叉树,分别进行三种不同的遍历:
先序遍历结果:
A B C D E F G H I J
中序遍历结果:
B C D A F E H J I G
后续遍历结果:
D C B J F J I H G A
下面给出代码:
二叉树类
public class BinaryTree
{
//根节点
private Node root;
//添加节点,提供给类外部调用
public void add(int data)
{
if (root==null) {
root=new Node(data);
}else
{
root.addNode(data);
}
}
//供给外部类进行调用
public void Display(){
if (root!=null) {
root.zhongDisplay();
System.out.println("");
System.out.println("后序遍历");
root.houDisplay();
System.out.println("");
System.out.println("先序遍历");
root.xianDisPlay();
}
}
//节点内部类
class Node{
//数据
private int data;
//左孩子
private Node leftchild;
//右孩子
private Node rightchild;
public Node(int data) {
this.data=data;
}
//添加节点方法,左孩子小于父亲节点,右孩子大于等于父亲节点
public void addNode(int data)
{
if (data<this.data) {
//判断是否是叶子节点
if (this.leftchild==null) {
this.leftchild=new Node(data);
}else {
this.leftchild.addNode(data);
}
}
else
{
if (this.data<=data) {
if (this.rightchild==null)
{
this.rightchild=new Node(data);
}
else {
this.rightchild.addNode(data);
}
}
}
}
public void xianDisPlay(){
//先序遍历
System.out.print(this.data+" ");
if (this.leftchild!=null) {
this.leftchild.xianDisPlay();
}
if (this.rightchild!=null) {
this.rightchild.xianDisPlay();
}
}
//输出接点,中序遍历输出结果,左根右,
public void zhongDisplay(){
//中序遍历
if (this.leftchild!=null) {
this.leftchild.zhongDisplay();
}
System.out.print(this.data+" ");
if (this.rightchild!=null) {
this.rightchild.zhongDisplay();
}
}
public void houDisplay()
{
//后序遍历
if (this.leftchild!=null) {
this.leftchild.houDisplay();
}
if (this.rightchild!=null) {
this.rightchild.houDisplay();
}
System.out.print(this.data+" ");
}
}
}
主方法:
public class BinaryTreeDemo {
public static void main(String[] args) {
BinaryTree binaryTree=new BinaryTree();
//添加数据
binaryTree.add(8);
binaryTree.add(3);
binaryTree.add(1);
binaryTree.add(6);
binaryTree.add(14);
binaryTree.add(23);
binaryTree.add(100);
binaryTree.add(22);
binaryTree.add(101);
binaryTree.add(32);
binaryTree.add(98);
binaryTree.Display();
}
}
输出结果: