1、树的节点包含一个数据元素,以及若干指向其子树的分支。节点拥有的子树的数量称为节点的度。节点的最大层次称为树的深度或高度。
2、二叉树是一种树形结构,其特点是每个节点至多有两棵子树,且子树有左右之分,次序不能随意颠倒。
3、满二叉树:一棵深度为k且有2^k - 1个节点的二叉树,称之为满二叉树。
4、完全二叉树:对一个深度为k,节点个数为n的二叉树,当且仅当每个节点都与深度为k的满二叉树中编号从1至n的节点一一对应时,称之为完全二叉树。
5、哈夫曼树:又称最优树,是一类带权路径长度最短的树。
6、二叉查找树(Binary Search Tree):对任一个节点,左子树的所有值都小于它,右子树的所有值都大于它。
7、AVL树:带有平衡条件的二叉查找树。
8、伸展树:任一个节点被访问后,它就要经过一系列的AVL树的旋转,将该节点放到根上。
9、B-树:另外一种常用的查找树。有几个特点,对于M阶的B树,首先,根节点如果不是叶子,则其子节点的数量在2-M之间。其次,除根之外,所有的非叶子节点的子节点数在M/2 - M之间。最后,所有的叶子节点有相同的深度。
节点的插入、删除、查询
/*
定义一颗BST树
*/
class BinNode>{
public T data;//数据域
public BinNode left;//左孩子
public BinNode right;//右孩子
public BinNode(T data, BinNode left, BinNode right) {
this.data = data;
this.left = left;
this.right = right;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public BinNode getLeft() {
return left;
}
public void setLeft(BinNode left) {
this.left = left;
}
public BinNode getRight() {
return right;
}
public void setRight(BinNode right) {
this.right = right;
}
}
/*
BST树的实现
*/
class BinTree>{
public BinNode root;//BST树的根节点
/*
BST树的初始化
*/
public BinTree(){
this.root=null;
}
/*
非递归实现BST树的节点插入操作
*/
public void non_insert(T data){
if(root==null){//1、树是空的,直接插入到根节点位置即可
root=new BinNode<>(data,null,null);
return;
}
BinNode parent=null;
BinNode cur=this.root;
//2、遍历,找到适合该节点插入的位置
while (cur!=null){
parent=cur;
if(cur.getData().compareTo(data)<0){//如果待插入的节点比根节点大,则从右子树继续查找
cur=cur.getRight();
}else if(cur.getData().compareTo(data)>0){
cur=cur.getLeft();
}else{
return;
}
}
if(parent.getData().compareTo(data)<0){//3、节点插入到合适的位置
parent.setRight(new BinNode<>(data,null,null));
}else if(parent.getData().compareTo(data)>0){
parent.setLeft(new BinNode<>(data,null,null));
}
}
/*
递归实现BST树的节点插入操作
*/
public void insert(T data){
this.root=insert(this.root,data);
}
private BinNode insert(BinNode root, T data) {
if(root==null){
return new BinNode<>(data,null,null);
}
if(root.getData().compareTo(data)<0){
root.setRight(insert(root.getRight(),data));
}else if(root.getData().compareTo(data)>0){
root.setLeft(insert(root.getLeft(),data));
}
return root;
}
/*
非递归实现节点的删除操作
*/
public void non_remove(T data){
if(data==null){//安全性检查
return;
}
BinNode parent=null;
while (root!=null){//1、遍历找到待删除点的位置
if(root.getData().compareTo(data)<0){
parent=root;
root=root.getRight();
}else if(root.getData().compareTo(data)>0){
parent=root;
root=root.getLeft();
}else{
break;
}
}
if(root==null){//跳出循环的节点进行安全性检查,如果为null,不符合条件。
return;
}
//2、待删除的点有两个孩子
if(root.getLeft()!=null && root.getRight()!=null){
//2.1、找到待删除点的前驱结点即左子树中的最右边的即最大的值覆盖待删除点
BinNode pre=root;
parent=root;
root=root.getLeft();
while (root.getRight()!=null){//找到最右边的结点
parent=root;
root=root.getRight();
}
pre.setData(root.getData());
}
//3、删除只有一个孩子或者没有孩子的
BinNode child=root.getLeft();
if(child==null){
child=child.getRight();
}
if(parent==null){//如果删除的是根节点
this.root=child;
}else{
if(root==parent.getLeft()){// 把root的child写入父节点的左孩子域
parent.setLeft(child);
}else{
parent.setRight(child);
}
}
}
/*
递归实现节点的删除操作
*/
public void remove(T data){
this.root=remove(this.root,data);
}
private BinNode remove(BinNode root, T data) {
if(root==null){
return null;
}
if(root.getData().compareTo(data)>0){
root=root.getRight();
root.setRight(remove(root,data));
}else if(root.getData().compareTo(data)<0){
root=root.getLeft();
root.setLeft(remove(root,data));
}else{
//处理有两个孩子的节点
if(root.getRight()!=null && root.getLeft()!=null){
BinNode pre=root.getLeft();
while (pre.getRight()!=null){
pre=pre.getRight();
}
root.setData(pre.getData());
//删除前驱结点的右节点
root.setLeft(remove(root.getLeft(),data));
}else{
//处理一个孩子的
if(root.getRight()!=null){
return root.getRight();
}else if(root.getLeft()!=null){
return root.getLeft();
}else{
return null;
}
}
}
return root;
}
/*
非递归实现树节点的查询
*/
public boolean non_query(T data){
if(data==null || root==null){
return false;
}
while (root!=null){
if(root.getData().compareTo(data)>0){
root=root.getLeft();
}else if(root.getData().compareTo(data)<0){
root=root.getRight();
}else{
return true;
}
}
return false;
}
/*
递归实现查询操作
*/
public boolean query(T data){
return query(this.root,data);
}
private boolean query(BinNode root,T data){
if(root==null || data==null){
return false;
}
if(root.getData().compareTo(data)==0){
return true;
}
while (root!=null){
if(root.getData().compareTo(data)<0){
return query(root.getRight(),data);
}else if(root.getData().compareTo(data)>0){
return query(root.getLeft(),data);
}
}
return false;
}
}