package cn.node;
public class BSTree<T> {
private BSNode<T> rootNode;
private BSNode<T> bsNode;
private BSNode<T> parentNode;
//节点的个数
public int size = 0;
/***
* 构造方法传入根节点
*
* @param rootNode
*/
public BSTree(BSNode<T> rootNode) {
this.rootNode = rootNode;
}
// 插入数据
public void insertData(T t) {
// 此时还没有任何节点在里面
if (size == 0) {
rootNode.data = t;
size++;
} else {
/***
* 1、先对二叉树进行遍历,如果在二叉树中存在该元素,则不插入,否则进行元素插入 2、如果没有找到该元素的位置则插入新的元素
*/
if (!searchNode(rootNode, t)) {
int result = compareTo(bsNode.data, t);
if(result > 0){
this.bsNode.lBsNode = new BSNode<T>();
this.bsNode.lBsNode.data = t;
}else{
this.bsNode.rBsNode = new BSNode<T>();
this.bsNode.rBsNode.data = t;
}
size++;
}
}
}
/**
*
* @param t
* @return
* 1、先找到要删除的节点
* 2、判断当前节点是否有左右节点
* 3、如果没有节点,那么直接删除
* 4、如果有左节点(右节点)那么直接将左右节点连接到要删除节点的父节点
* 5、如左右节点都存在,那么首先找到要删除节点,右子树最小的替换,然后删除最小的
*/
public boolean removeData(T t) {
//查找到要删除的节点
if(searchNode(rootNode, t)){
int i = 0;
if(parentNode.lBsNode != null && parentNode.lBsNode.equals(bsNode)) i = -1;
else if(parentNode.rBsNode != null && parentNode.rBsNode.equals(bsNode)) i = 1;
//如果没有左右节点
if(bsNode.lBsNode == null && bsNode.rBsNode == null){
parentNode.data = null;
if(i == -1){
parentNode.lBsNode = null;
}else if(i == 1){
parentNode.rBsNode = null;
}
bsNode = null;
}else{
if(bsNode.lBsNode != null && bsNode.rBsNode != null){
BSNode<T> mbsNode = findMinNode(bsNode.lBsNode);
bsNode.data = mbsNode.data;
/**
* 如果找到的最小节点有右分支,那么将
*/
if(mbsNode.rBsNode != null){
mbsNode.data = mbsNode.rBsNode.data;
mbsNode.rBsNode = null;
}
}else{
bsNode = bsNode.lBsNode != null ? bsNode.lBsNode : bsNode.rBsNode;
if(i == -1){
parentNode.lBsNode = bsNode;
}else{
parentNode.rBsNode = bsNode;
}
}
}
}else{
return false;
}
return true;
}
/**
* 递归的方式对节点进行匹配
*
* @param bsNode二叉树的根节点
* @param t需要插入的元素
* @return如果返回true表示查询到要找的节点
*/
public boolean searchNode(BSNode<T> bsNode, T t) {
if (bsNode == null || bsNode.data == null)
return false;
else{
this.bsNode = bsNode;
}
int result = compareTo(bsNode.data, t);
if (result == 0)
return true;
// >0 表示源节点大于当前节点表示的数据,所以在源节点的左子树中查询
if (result > 0){
parentNode = bsNode;
return searchNode(bsNode.lBsNode, t);
}
// <0表示源节点小于当前节点的数据,所以继续在节点的右子树中查询
if (result < 0){
parentNode = bsNode;
return searchNode(bsNode.rBsNode, t);
}
return true;
}
/**
*
* @param resource表示树中已经存在的节点的数据
* @param target表示需要插入的节点的值
* @return 0 表示相同 >0表示目标小于源 <0表示目标大于源
*/
public int compareTo(T resource, T target) {
if (resource.equals(target)) {
return 0;
}
if (target instanceof String) {
String res = (String) resource;
String tar = (String) target;
return res.compareTo(tar);
}
if (target instanceof Integer) {
Integer res = (Integer) resource;
Integer tar = (Integer) target;
return res.compareTo(tar);
}
return 0;
}
/**
*
* @param bsNode找到值最小的节点
* @return
*/
public BSNode<T> findMinNode(BSNode<T> bsNode){
BSNode<T> nbsNode = null;
if(bsNode != null){
nbsNode = bsNode;
findMinNode(bsNode.lBsNode);
}
return nbsNode;
}
}
public class BSTree<T> {
private BSNode<T> rootNode;
private BSNode<T> bsNode;
private BSNode<T> parentNode;
//节点的个数
public int size = 0;
/***
* 构造方法传入根节点
*
* @param rootNode
*/
public BSTree(BSNode<T> rootNode) {
this.rootNode = rootNode;
}
// 插入数据
public void insertData(T t) {
// 此时还没有任何节点在里面
if (size == 0) {
rootNode.data = t;
size++;
} else {
/***
* 1、先对二叉树进行遍历,如果在二叉树中存在该元素,则不插入,否则进行元素插入 2、如果没有找到该元素的位置则插入新的元素
*/
if (!searchNode(rootNode, t)) {
int result = compareTo(bsNode.data, t);
if(result > 0){
this.bsNode.lBsNode = new BSNode<T>();
this.bsNode.lBsNode.data = t;
}else{
this.bsNode.rBsNode = new BSNode<T>();
this.bsNode.rBsNode.data = t;
}
size++;
}
}
}
/**
*
* @param t
* @return
* 1、先找到要删除的节点
* 2、判断当前节点是否有左右节点
* 3、如果没有节点,那么直接删除
* 4、如果有左节点(右节点)那么直接将左右节点连接到要删除节点的父节点
* 5、如左右节点都存在,那么首先找到要删除节点,右子树最小的替换,然后删除最小的
*/
public boolean removeData(T t) {
//查找到要删除的节点
if(searchNode(rootNode, t)){
int i = 0;
if(parentNode.lBsNode != null && parentNode.lBsNode.equals(bsNode)) i = -1;
else if(parentNode.rBsNode != null && parentNode.rBsNode.equals(bsNode)) i = 1;
//如果没有左右节点
if(bsNode.lBsNode == null && bsNode.rBsNode == null){
parentNode.data = null;
if(i == -1){
parentNode.lBsNode = null;
}else if(i == 1){
parentNode.rBsNode = null;
}
bsNode = null;
}else{
if(bsNode.lBsNode != null && bsNode.rBsNode != null){
BSNode<T> mbsNode = findMinNode(bsNode.lBsNode);
bsNode.data = mbsNode.data;
/**
* 如果找到的最小节点有右分支,那么将
*/
if(mbsNode.rBsNode != null){
mbsNode.data = mbsNode.rBsNode.data;
mbsNode.rBsNode = null;
}
}else{
bsNode = bsNode.lBsNode != null ? bsNode.lBsNode : bsNode.rBsNode;
if(i == -1){
parentNode.lBsNode = bsNode;
}else{
parentNode.rBsNode = bsNode;
}
}
}
}else{
return false;
}
return true;
}
/**
* 递归的方式对节点进行匹配
*
* @param bsNode二叉树的根节点
* @param t需要插入的元素
* @return如果返回true表示查询到要找的节点
*/
public boolean searchNode(BSNode<T> bsNode, T t) {
if (bsNode == null || bsNode.data == null)
return false;
else{
this.bsNode = bsNode;
}
int result = compareTo(bsNode.data, t);
if (result == 0)
return true;
// >0 表示源节点大于当前节点表示的数据,所以在源节点的左子树中查询
if (result > 0){
parentNode = bsNode;
return searchNode(bsNode.lBsNode, t);
}
// <0表示源节点小于当前节点的数据,所以继续在节点的右子树中查询
if (result < 0){
parentNode = bsNode;
return searchNode(bsNode.rBsNode, t);
}
return true;
}
/**
*
* @param resource表示树中已经存在的节点的数据
* @param target表示需要插入的节点的值
* @return 0 表示相同 >0表示目标小于源 <0表示目标大于源
*/
public int compareTo(T resource, T target) {
if (resource.equals(target)) {
return 0;
}
if (target instanceof String) {
String res = (String) resource;
String tar = (String) target;
return res.compareTo(tar);
}
if (target instanceof Integer) {
Integer res = (Integer) resource;
Integer tar = (Integer) target;
return res.compareTo(tar);
}
return 0;
}
/**
*
* @param bsNode找到值最小的节点
* @return
*/
public BSNode<T> findMinNode(BSNode<T> bsNode){
BSNode<T> nbsNode = null;
if(bsNode != null){
nbsNode = bsNode;
findMinNode(bsNode.lBsNode);
}
return nbsNode;
}
}