二叉树
一、二叉树的形成:
二叉树是来源与我们熟知的二分查找。将二分查找分成两个部分,写成树的形式。
上图就是将有序的数组进行二分查找后写出的二叉树
二、二叉树的特点
1、右孩子>父节点>左孩子
2、每个节点最多有两个孩子
3、第n层节点的个数为2^n,树的高度就是Log2(n)
三、代码实现
**1、**前驱:待删除节点左子树中值最大的点
**2、**后驱:待删除节点的右子树中值最小的节点
**3、**插入操作:
将待插入数值与根节点比较,比根大就放右边,比跟小放左边,接着依次继续比较。若根为null则待插入数值直接为根。
**4、**删除操作:
(1)当带删除节点有两个孩子时,找到该节点的前驱或者后驱,将其前驱或者后驱的值赋给带删除节点,然后删除该前驱或后驱节点。
(2)待删除节点只有一个孩子时,将该节点的孩子直接复制给它。
(3)待删除节点没有孩子时,相当于该节点的孩子为null,则操作步骤同(2)。
5、代码
package com.company.BST;
import java.lang.reflect.Array;
import java.util.Arrays;
class BSTNode<T extends Comparable<T>>{
private T data; // 数据域
private BSTNode<T> left; // 左孩子域
private BSTNode<T> right; // 右孩子域
public BSTNode(T data, BSTNode<T> left, BSTNode<T> right) {
this.data = data;
this.left = left;
this.right = right;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public BSTNode<T> getLeft() {
return left;
}
public void setLeft(BSTNode<T> left) {
this.left = left;
}
public BSTNode<T> getRight() {
return right;
}
public void setRight(BSTNode<T> right) {
this.right = right;
}
}
/**
* BST树的实现
* @param <T>
*/
class BST<T extends Comparable<T>>{
private BSTNode<T> root; // 指向根节点
/**
* BST树的初始化
*/
public BST() {
this.root = null;
}
/**
* BST树的插入操作
* @param data
*/
public void insert(T data){
if(this.root==null){//树为空,就直接成为根节点
BSTNode<T> node=new BSTNode<>(data,null,null);
return;
}
BSTNode<T> cur=this.root;
BSTNode<T> pre=null;
while (cur!=null){//到最后的非叶子节点
if(cur.getData().compareTo(data)>0){//比根节点小-到左孩子
pre=cur;
cur=cur.getLeft();}
else if(cur.getData().compareTo(data)<0){//插入数比右孩子小
pre=cur;
cur=cur.getRight();//更新cur }
}
else {
return;
}
}
BSTNode<T> node=new BSTNode<>(data,null,null);//生成新节点,把节点的地址写入父节点的地址域
//需要再次和插入的节点比较
if(cur.getData().compareTo(data)>0){//比根节点小-到左孩子
pre.setLeft(new BSTNode<>(data,null,null));}
if(cur.getData().compareTo(data)<0) {
pre.setRight(new BSTNode<>(data,null,null));
}
}
public void remove(T data){
//搜索BST数 找到要删除的节点
//判断该节点是否有前驱或后继
//删除有一个孩子的节点,或没有孩子的节点
if(this.root==null){
return; }
BSTNode<T> cur=this.root;
BSTNode<T> pre=null;
while (cur!=null){
if(cur.getData().compareTo(data)>0){
pre=cur;
cur=cur.getLeft();
}
if(cur.getData().compareTo(data)<0){
pre=cur;
cur=cur.getRight();
}
else {//找到了待删除的值 直接返回
break;
}
}
if(cur==null){//要删除的值不在树里
return;
}
if(cur.getRight()!=null&&cur.getLeft()!=null){//有两个孩子
BSTNode<T> old=cur;
pre=cur;
cur=cur.getLeft();
if(cur.getRight()!=null){//找当前节点的前驱
cur=cur.getRight();
}
old.setData(cur.getData());//将前驱赋值给带删除节点
// cur=null;//删除前驱//因为当前驱替代了要删除节点时,再删除该前驱即就是删除只有一个孩子或没有孩子的节点
// return;
}
//if(cur.getLeft()==null||cur.getRight()==null){//当带删除节点只有一个孩子或者没有孩子时
BSTNode<T> chlid=cur.getLeft();//从左边树开始
if(chlid==null){//如果左边树不存在
chlid=cur.getRight();//则只有右边树
}
if(pre==null){//当删的时根节点
this.root=chlid;//把根下面的孩子赋值给根
}
else {
if (pre.getRight() == cur) {//只有右孩子
pre.setRight(chlid);
}
else {
pre.setLeft(chlid);
}
}
}
public static void main(String[] args) {
BST<Integer> bst = new BST<>();
int[] ar = {58,23,82,12,35,69,87,18,47,74,95};
for (int val : ar) {
bst.insert(val);
}
System.out.println();
}
}