尽管不明白用java写数据结构的好处究竟有多大,但是了解了SBTree之后我就想尝试着去实现。最终做出了一个不规范的类似物。
希望大触们的意见!
下面的是带着草稿的源码。
import java.util.ArrayList;
public class SBTree<UnknownType extends Comparable<UnknownType>>{
public int capacity=0;
private SBTreeNode NIL=new SBTreeNode(-1,null);
private int head=-1;
public int size=0;
private ArrayList<SBTreeNode> root;
public SBTree(){
root=new ArrayList<SBTreeNode>();
NIL.size=0;
}
@Override
public String toString(){
return "size="+this.size+",capacity="+this.capacity+"\r\n"+this.root.toString();
}
//重写的toString方法
private SBTreeNode get(int index){
if(index==-1) return NIL;
return this.root.get(index);
}//对节点返回的内部方法,index为-1时返回NIL值,其余则与ArrayList相同
public UnknownType getValue(int index){
return this.get(index).value;
}
//返回节点值,index为-1时返回null值,其余则与ArrayList相同
private void leftRotate(int index){
if(index==-1) return;
SBTreeNode leftone=this.get(index);
if(leftone.right==-1) {System.out.println("error");return;}
//System.out.println(leftone);
SBTreeNode rightone=this.get(leftone.right);
leftone.right=rightone.left;
this.get(rightone.left).parent=leftone.index;
rightone.left=index;
leftone.size-=1+this.get(rightone.right).size;
rightone.size+=1+this.get(leftone.left).size;
if(index!=this.head){
if(leftone.index==this.get(this.get(leftone.parent).left).index)
this.get(leftone.parent).left=rightone.index;
else this.get(leftone.parent).right=rightone.index;
}
else this.head=rightone.index;
rightone.parent=leftone.parent;
leftone.parent=rightone.index;
//System.out.println(leftone);
}//树的左旋
private void rightRotate(int index){
if(index==-1) return;
SBTreeNode rightone=this.get(index);
if(rightone.left==-1) {System.out.println("error");return ;}
//System.out.println(rightone);
SBTreeNode leftone=this.get(rightone.left);
rightone.left=leftone.right;
this.get(leftone.right).parent=rightone.index;
leftone.right=index;
rightone.size-=1+this.get(leftone.left).size;
leftone.size+=1+this.get(rightone.right).size;
if(this.get(rightone.parent).index!=-1){
if(rightone.index==this.get(this.get(rightone.parent).right).index)
this.get(rightone.parent).right=leftone.index;
else this.get(rightone.parent).left=leftone.index;
}
else this.head=leftone.index;
leftone.parent=rightone.parent;
rightone.parent=leftone.index;
//System.out.println(rightone);
}//树的右旋
private void maintain(int index){
if(index==-1) return;
SBTreeNode leftone=this.get(this.get(index).left);
SBTreeNode rightone=this.get(this.get(index).right);
if(this.get(leftone.left).size>rightone.size){
rightRotate(index);
maintain(leftone.right);
maintain(leftone.index);
}
if(this.get(leftone.right).size>rightone.size){
leftRotate(leftone.index);
rightRotate(index);
maintain(leftone.left);
maintain(leftone.right);
maintain(leftone.index);
}
if(this.get(rightone.right).size>leftone.size){
leftRotate(index);
maintain(rightone.left);
maintain(rightone.index);
}
if(this.get(rightone.right).size>leftone.size){
rightRotate(rightone.index);
leftRotate(index);
maintain(rightone.right);
maintain(rightone.left);
maintain(rightone.index);
}
}//特别的SBTree的maintain操作
/*private void maintain(int index,boolean flag){
if(index==-1) return;
SBTreeNode leftone=this.get(this.get(index).left);
SBTreeNode rightone=this.get(this.get(index).right);
if(!flag){
if(this.get(leftone.left).size>rightone.size)
rightRotate(index);
if(this.get(leftone.right).size>rightone.size){
leftRotate(leftone.index);
rightRotate(index);
}
}
if(flag){
if(this.get(rightone.right).size>leftone.size)
leftRotate(index);
if(this.get(rightone.right).size>leftone.size){
rightRotate(rightone.index);
leftRotate(index);
}
}
maintain(leftone.index,false);
maintain(leftone.index,true);
maintain(index,false);
maintain(index,true);
}//特别的优化的maintain操作*/
public boolean add(UnknownType value){
SBTreeNode newNode=new SBTreeNode(this.capacity,value),result=null;
if(!this.root.add(newNode)) return false;
else{
this.size++;
this.capacity++;
if(this.head==-1) this.head=newNode.index;
else{
int search=this.head,flag=1;
while(search!=-1){
result=this.get(search);
if((flag=value.compareTo(result.value))>0) search=result.right;
else search=result.left;
result.size++;
}
if(flag>0) result.right=newNode.index;
else result.left=newNode.index;
newNode.parent=result.index;
for(search=newNode.index;search!=-1;search=this.get(search).parent)
this.maintain(search);
//for(search=newNode.index;search!=this.head;search=this.get(search).parent)
//this.maintain(search,this.get(search).value.compareTo(this.get(this.get(search).parent).value)>0);
}
//this.print_r();
return true;
}
}
//树的插入操作,成功返回true,失败返回false
private void printr(int index,int floor){
if(index==-1) return ;
System.out.println(floor+" floor: "+this.get(index));
printr(this.get(index).left,floor+1);
printr(this.get(index).right,floor+1);
}//内部对每个子树的打印递归方法
public void print_r(){
System.out.println("************************");
printr(this.head,0);
System.out.println("************************");
}
private void prints(int index,int floor){
if(index==-1) return ;
prints(this.get(index).left,floor+1);
System.out.println(floor+" floor: "+this.get(index));
prints(this.get(index).right,floor+1);
}//内部对每个子树的打印递归方法2
private void print(int index,int floor){
if(index==-1) return ;
print(this.get(index).right,floor+1);
System.out.println(floor+" floor: "+this.get(index));
print(this.get(index).left,floor+1);
}//内部对每个子树的打印递归方法3
//直接打印该树,中序遍历。
public void print_s(boolean flag){
System.out.println("************************");
if(flag) prints(this.head,0);
else print(this.head,0);
System.out.println("************************");
}
//直接打印该树,true为顺序,false为倒序。
public int searchByValue(UnknownType value){
for(int search=this.head;search!=-1;){
int flag=value.compareTo(this.get(search).value);
if(flag>0) search=this.get(search).right;
else if(flag<0) search=this.get(search).left;
else return search;
}
return -1;
}
//返回该树中某一个值与其相等的节点index,否则为-1。
public int searchBySequence(int index){
int flag=this.size;
for(int search=this.head;search!=-1;){
SBTreeNode result=this.get(search);
flag=index-this.get(result.left).size;
if(flag<=0) search=result.left;
else if(flag==1) return search;
else{
search=result.right;
index=flag;
}
}
return -1;
}
//返回该树中第i小的节点index,否则为-1。
public boolean exists(int index){
if(this.capacity<index || this.root.get(index).index!=index) return false;
else return true;
}//分辨是否为碎片节点。
public void adjust(){
System.out.println("adjusted when rate="+(double)this.size/this.capacity);
int j=0;
for(int i=this.capacity-1;i>j;i--){
if(this.exists(i)){
for(;i>j;j++)
if(!this.exists(j)){
SBTreeNode result=this.get(i);
this.get(result.left).parent=j;
this.get(result.right).parent=j;
if(i==this.head) this.head=j;
else{
if(this.get(result.parent).left==i) this.get(result.parent).left=j;
else if(this.get(result.parent).right==i) this.get(result.parent).right=j;
else System.out.println("wrong when i="+i+" j="+j);
}
result.index=j;
this.root.set(j++,result);
this.root.remove(i);
this.capacity--;
break;
}
}
else{
this.root.remove(i);
this.capacity--;
}
}
}//碎片整理函数,必要时调用。
private boolean deleteByIndex(int index){
SBTreeNode deleting=this.get(index);
if(index<0 || deleting==null || deleting==NIL) return false;
else {
int parent=deleting.parent;
while(deleting.left!=-1 || deleting.right!=-1){
if(this.get(deleting.left).size>this.get(deleting.right).size) this.rightRotate(index);
else this.leftRotate(index);
}
if(this.get(deleting.parent).left==index) this.get(deleting.parent).left=-1;
else if(this.get(deleting.parent).right==index) this.get(deleting.parent).right=-1;
else System.out.println("fault");
for(SBTreeNode result=deleting;result.index!=-1;result=this.get(result.parent))
result.size--;
for(;deleting.index!=parent;deleting=this.get(deleting.parent))
maintain(deleting.index);
maintain(parent);
this.root.set(index,NIL);
deleting=null;
this.size--;
return true;
}
}//删除节点的内部方法
public boolean deleteByIndex(int index,boolean flag){
if(flag) this.adjust();
return deleteByIndex(index);
}
//flag为true时进行adjust整理。false则不进行。
//将节点index为index的节点删除,重复删除返回false。
public boolean deleteBySequence(int i,boolean flag){
if(flag) this.adjust();
return deleteByIndex(this.searchBySequence(i));
}
//flag为true时进行adjust整理。false则不进行。
//将节点大小排名为i的节点删除,重复删除返回false。
public int size(){
return this.size;
}
//获得size值
class SBTreeNode{
int index;
int size=1;
int left=-1;
int right=-1;
int parent=-1;
UnknownType value=null;
@Override
public String toString(){
if(this.value==null) return "NULL NODE";
else return this.index+":"+this.value.toString()+" (which has "+this.size+" node parent is node "+this.parent+" )";
}
public SBTreeNode(int index,UnknownType value){
this.index=index;
this.value=value;
}
}
}
写完初步运行尚可,问题是:
NIL设置成静态常量会报错。(jdk8)
另外maintain方法用的是效率低的那种。
还有UnknownType写成没有实现Comparable接口的会怎么样没有试过
最后还有问题,就是假如节点的left和right设置成节点类型还是int靠tree检索好不清楚