package mylearn;
public class binarysorttree {
private dot root;
public void add(dot d)
{
if(root==null)//核心,当root空时就直接把第一个add的作为root,这样就能调用indexorder
{
this.root=d;
}else{this.root.add(d);}
}
public void indexorder()
{
if(root==null)
{
return;
}else{this.root.indexorder();}
}
//封装一下查找删除节点和父节点的方法
public dot searchwantdel(int value)
{
if(root==null)
{
return null;
}else{ return this.root.search(value);}
}
public dot searchfatherdot(int value)
{
if(root==null)
{
return null;
}else{ return this.root.searchfather(value);}
}
public void deldot(int value)
{
if(root==null){return;}
dot target=searchwantdel(value);
dot father=searchfatherdot(value);
System.out.println("目标节点"+target+"父节点"+father);
if(target==null){return ;}//没找到要删除节点
if(root.left==null&&root.right==null){ root=null;}//发现树只有个根节点
//target是叶子节点时,看target是father左子节点还是右子节点
if(father!=null)//避免空指针
{
if(target.left==null&&target.right==null&&father.left==target){father.left=null;}//当是father左子节点
if(target.left==null&&target.right==null&&father.right==target){father.right=null;}//当是father左子节点
}
if(father==null)//当father=null时还用上面代码会出现空指针异常/father=null相当于target=root直接让左或右的叶子节点为root
{
if(target.left!=null&&target.right==null){root=target.left;}
if(target.right!=null&&target.left==null){root=target.right;}
}
if(target.left!=null&&target.right!=null)//第二种情况左右子树都有 找右子树最小节点由temp保存,删除此最小节点,并且target.value=temp.value//是改值不是改节点!!!
{
dot RighttreeMin=delRightTreeMin(target.right);
target.value=RighttreeMin.value;
}
if((target.left==null&&target.right!=null&&father!=null)||(target.left!=null&&target.right==null&&father!=null))//第三种情况只有一边有子树
{
if(father.left==target&&target.left!=null)
{
father.left=target.left;
}
if(father.left==target&&target.right!=null)
{
father.left=target.right;
}
if(father.right==target&&target.left!=null)
{
father.right=target.left;
}
else
{
father.right=target.right;
}
}
if((target.left==null&&target.right!=null&&father==null)||(target.left!=null&&target.right==null&&father==null))
{
if(target.left!=null){root=target.left;}
if(target.right!=null){root=target.right;}
}
}
public dot delRightTreeMin(dot targetright)//一直往左找找的最小
{
dot temp=targetright;
while(temp.left!=null)
{
temp=temp.left;
}
deldot(temp.value);//删除最小节点
return temp;
}
//main调试
public static void main(String[] args) {
int []arr={1,3,5,7,9,10,12};
binarysorttree tree1=new binarysorttree();
for(int i=0;i<arr.length;i++)
{
tree1.add(new dot(arr[i]));//添加时就创建
}
tree1.indexorder();
System.out.println("search");
System.out.println("67的父节点"+tree1.searchfatherdot(7));
System.out.println(tree1.searchwantdel(7));
// System.out.println("删除叶子节点");
// tree1.deldot(8);
// tree1.deldot(7);
// tree1.deldot(3);
// tree1.indexorder();
tree1.deldot(2);
tree1.deldot(5);
tree1.deldot(9);
tree1.deldot(12);
tree1.deldot(7);
tree1.deldot(3);
tree1.deldot(10);
tree1.deldot(1);
tree1.indexorder();
}
}
class dot {
@Override
public String toString() {
return "value" + this.value;
}
int value;
dot left;
dot right;
public dot(int value) {
this.value = value;
}
public void add(dot d) {
if (d.value < this.value)
{
if (this.left == null)
{
this.left = d;
}
else
{
this.left.add(d);
}
}
else //大于等于放右子树
{
if (this.right == null)
{
this.right = d;
}
else
{
this.right.add(d);
}
}
}
public void indexorder() {
if (this.left != null) {
this.left.indexorder();
}
System.out.println(this);
if (this.right != null) {
this.right.indexorder();
}
}
public dot search(int value)
{
if(value == this.value)
{
return this;
}
else if(value < this.value)
{
if(this.left == null)
{
return null;
}
return this.left.search(value);
}
else
{
if(this.right == null)
{
return null;
}
return this.right.search(value);
}
}
public dot searchfather(int value) {
if ((this.left != null && this.left.value == value) || (this.right != null && this.right.value == value))//!=null为了避免空指针异常
{
return this;
}
else
{
if (value < this.value )
{
if(this.left==null){return null;}
return this.left.searchfather(value);
}
else if (value >= this.value )
{
if(this.right==null) {return null;}
return this.right.searchfather(value);
}
} return null;
}
}
使用数组
数组未排序 优点:直接在尾部添加,速度快。缺点:查找速度慢
数组排序 优点:可以用二分查找法 查找速度快 缺点:为保证数组有序 在添加新数据时,快速找到添加位置,但是后面的数要整体后移,速度慢。
使用链表
不管链表是否有序,查找速度都慢,添加数据比数组快,不需要整体后移
使用二叉排序树 不管添加还是查找都快