public class BinarySortTree {
node root;
public BinarySortTree(int[] ints) {
for (int i = 0; i <ints.length ; i++) {
add(new node(ints[i]));
}
}
public void add(node nodes){
if (root==null){
root=nodes;
}else {
root.add(nodes);
}
}
public void InfixOrder(){ //添加的时候 左<子<右 所以中序遍历时,恰好完成排序输出
if (root!=null){
root.InfixOrder(root);
}else {
System.out.println("not found!");
}
}
public node search(int value){
if (root!=null){
return root.search(value);
}
return null;
}
public node Parent(int value){
if (root!=null){
return root.SearchParent(value);
}else {
return null;
}
}
public int DelMin( node target){ //当target的子节点有两个时的删除
node tem=target;
while (target.left!=null){
tem=tem.left;
}
//删除方法:
// 1. tem=null; 错误的删除方法
// 2. delete(tem.value); //虽然简洁,但是不够直接
//3. 优化 //基于已有的信息,可直接的删除
node parent = Parent(tem.value);
parent.left=null;
return tem.value;
}
public void delete(int value){
if (root!=null){
node target = search(value);
if (target==null){
return;
}
//根节点就是要查找节点且二叉排序树只有这一节点时
// if (target.left==null&&target.right==null){
// // root=null; 这里虽然是考虑只有根节点,但是也满足叶子节点,所以最好是记得直接结束函数
// target=null;
// return; //叶子节点也会被误杀
// }
if (root.left==null&&root.right==null){
root=null;
return;
}
node parent = Parent(value); //if the root?
//叶子节点
if (target.left==null&&target.right==null){
if (parent.left!=null&&parent.left.value==value){
parent.left=null;
}else if (parent.right!=null&&parent.right.value==value){
parent.right=null;
}
}else if (target.left!=null&&target.right!=null){ //target有双节点时
// int min = DelMin(target); 注意虽是从一直从左找最小,但是设置起始查找位置为target.right
int min=DelMin(target.right); //保证代替值 大于target左(起始位置设置为target的右), 小于target右(往左找)
target.value=min; //或 target的左, 往右找
}else {//待删除节点只有一个节点时
if (target.left!=null){ //确定待删除节点的唯一子节点的位置,当target的子节点在左
if (parent!=null){ //判断父节点是否为空
//判断待删除节点相对于父节点的位置,以便待删除节点的子节点去补位
if (parent.left!=null&&parent.left.value==value){ // target相对父节点在左
parent.left=target.left;
}else {// target相对父节点在右
parent.right=target.left;
}
}else {
root=target.left;
}
}else { //target子节点在右
if (parent!=null){ //注意父节点是否为空
if (parent.left!=null&&parent.left.value==value){ // target相对父节点在左
parent.left=target.right;
}else {//在右
parent.right=target.right;
}
}else {
root=target.right;
}
}
}
}
}
}
class node{
int value;
node left;
node right;
//查找待删除的节点,在类里面写方法时,天然就可以使用this,因为调用这个类里方法的一定是这个类的实例,可能这就是为甚么不在二叉排序树实现查找方法
public node search(int value){
if (this.value==value){
return this;
}else if (this.value<value){
if (this.right==null){
return null;
}
return this.right.search(value);
}else{
if (this.left==null){
return null;
}
return this.left.search(value);
}
}
//查找待删除节点的父节点
public node SearchParent(int value){
if ((this.left!=null&&this.left.value==value)||(this.right!=null&&this.right.value==value)){
return this;
}else { //注意还是让this.value<value来引领查找方向,虽然是查找父节点,但是不应该忘记二分树的特性
if (this.value<value&&this.right!=null){
return this.right.SearchParent(value); //是否一定要加return 哪个函数调用它最后就把值返回给那个函数
}else if (this.value>=value&&this.left!=null){
return this.left.SearchParent(value);
}else {
return null;
}
}
}
public void add(node Node){
if (Node==null){
return;
}
if (Node.value<this.value){ //当前调用这个add函数的节点就是this
if (this.left==null){
this.left=Node;
}else {
this.left.add(Node);
}
}else {
if (this.right==null){
this.right=Node;
}else {
this.right.add(Node);
}
}
}
@Override
public String toString() {
return "node{" +
"value=" + value +
'}';
}
public node(int value) {
this.value = value;
}
public void InfixOrder(node root){
if (root.left!=null){
root.InfixOrder(root.left);
}
System.out.println(root);
if (root.right!=null){
root.InfixOrder(root.right);
}
}
}
二叉排序树的添加,删除,查找代码
最新推荐文章于 2024-05-16 10:30:00 发布