【Java数据结构】二叉树
【Java数据结构】二叉树
一、二叉树的逻辑结构
1、二叉树的定义

2、特殊的二叉树
①满二叉树
- 如果一颗二叉树中,所有分支结点都存在左子树和右子树,并且所有叶子都在同一层上,则这样的二叉树称为满二叉树。
- 叶子只能出现在最下一层
- 只有度为0和度为2的结点

②完全二叉树
- 如果一颗二叉树中,除了最底层结点可能没有填满之外,其余每层结点树都打到最大值,并且最下面一层的结点都集中在该层最左边的若干位置。

- 堆就是一颗完全二叉树,同时保证父子结点的顺序关系。
算法基础三:分治算法---基于二叉堆的优先队列 - DarkerG - 博客园 (cnblogs.com)
③二叉搜索树BST
Binary Search Tree
- 二叉搜索树是由数值的数,二叉搜索树是一个有序树。
- 若它的左子树不为空,则左子树上所有结点的值均小于它的根节点的值。
- 若它的右子树不为空,则右子树上所有结点的值均大于它的根节点的值。
- 它的左、右子树也分别是二叉排序树。

④平衡二叉搜索树AVL
- AVL(Adelson-Velsky and Landis)树
- 它是一棵空树或者它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一颗平衡二叉树。

⑤霍夫曼树
⑥红黑树R-B Tree
⑦B-Tree(B-树或者B树)
⑧B+ Tree(B+树)
二、二叉树的遍历操作定义
1、遍历的种类

- 前中后序遍历的操作

- 层序遍历:
- 从二叉树的根节点开始,从上至下逐层遍历,同一层按照从左到右的顺序对结点逐个访问。
2、遍历操作举例

- 前序遍历:ABDGCEF
- 中序遍历:DGBAECF
- 后序遍历:GDBEFCA
- 层序遍历:ABCDEFG
确定一颗二叉树,任何遍历操作都是唯一的。但是根据任一遍历操作却不能确定一棵二叉树
- 可以通过前序遍历和中序遍历可以唯一确定这棵二叉树
- 可以通过后序遍历和中序遍历可以唯一确定一棵二叉树
三、二叉树的存储结构及实现
1、二叉树的Java接口定义
public interface BinaryTreeInterface<T>{
public void preOrder(); //前序
public void inOrder();
public void postOrder();
public void levelOrder();
//根据前序遍历序列构建二叉树
public void createBiTree(SequentialList<T> treeElemnt);
}
2、顺序存储结构


图示

代码
public class SequentialTree<T> implements BinaryTreeInterface{
protected T[] seqTree; //二叉树顺序存储数组
private final static int TREE_MAX_SIZE=100;//存储容量
//成员函数实现二叉树接口函数
}
特点
- 浪费存储空间,最坏的情况就是右斜树,一棵深度为k的右斜树只有k个结点,却需要分配2^k-1个存储单元。事实上,二叉树的顺序存储结构一般仅适合存储完全二叉树。
3、二叉链表

public class BiNode<T>{
private T data; //定义结点泛型数据域
private BiNode<T> lChild,rChild; //定义结点左、右孩子引用域
public BiNode(T element){//构造数据域为element值的结点
this.data=element;
}
public T getDate(){return data;}//获取数据域
public void setDate(T data) {this.data=data;}
public BiNode<T> getlChild(){return lChild;}
public BiNode<T> setlChild(){this.lChild = lChild;}
public BiNode<T> getrChild(){return rChild;}
public BiNode<T> setrChild(){this.rChild = rChild;}
}
图示

二叉链表的实现
在BinaryTree类中,通过定义BiNode类型根节点变量root实现二叉链表存储结构。BinaryTree类实现BinaryTreeInterface接口定义的方法。
public class BinaryTree<T> implements BinaryTreeInterface{
protected BiNode<T> root;
//成员函数实现二叉树接口算法
}
- 二叉树初始化(BinaryTree)---构造器
public BinaryTree(){
root=null;
}
- 前序遍历(preOrder)
- 递归算法
public void preOrder(){//前序遍历入口
preOrder(root);
}
private void preOrder(BiNode node){//前序遍历递归实现
if(node==null){
return;
}else{
System.out.print(node.getData()+" ");//访问当前节点的数据域
preOrder(node.getlChild()); //前序递归遍历node的左子树
preOrder(node.getrChild()); //前序递归遍历node的右子树
}
}
- 中序遍历(inOrder)

- 后序遍历(postOrder)

- 层序遍历(levelOrder)


- 算法的伪代码描述

- 算法实现
public void levelOrder(){
QueueInterface<BiNode> queue = new LinkedQueue<BiNode>();
if(root==null){
return;
}else{
queue.enQueue(root); //根引用入队
while(!queue.isEmpty()){
BiNode tempNode = queue.deQueue();//出队
System.out.print(tempNode.getData()+" ");//输出结点数据域
if(tempNode.getlChild() !=null) //结点非空左孩子入队
queue.enQueue(tempNode.getlChild());
if(tempNode.getrChild() !=null) //结点非空右孩子入队
queue.enQueue(tempNode.getrChild());
}
}
}

浙公网安备 33010602011771号