晚上好。
我正在尝试实现AVL树,并且在轮换过程中复制节点时出现问题:
所以,我想知道是否有办法解决这个限制 这是该类的完整代码(main只是对initialise()的调用),其他一切行为都正确,所以如果我能设法在旋转中正确地复制节点,我会有一个工作的AVL树。 / p>
提前感谢您的帮助。
import java.util.ArrayList;
public class NodeQ
{
static boolean isEmpty=true;
private int h=1;
private double x, y;
private ArrayList<Segment> segmentsStarting=new ArrayList<Segment>();
private NodeQ left=null, right=null;
public NodeQ(double abs, double ord) {x=abs; y=ord;}
public NodeQ(NodeQ Q) {this.x=Q.x; this.y=Q.y; this.segmentsStarting=Q.segmentsStarting;}
public double getX() {return x;}
public double getY() {return y;}
public NodeQ getLeft() {return left;}
public NodeQ getRight() {return right;}
public ArrayList<Segment> getSegmentsStarting() {return segmentsStarting;}
public int getH(){return h;}
public void setX(double abs) {x=abs;}
public void setY(double ord) {y=ord;}
public void setLeft(NodeQ l) {left=l;}
public void setRight(NodeQ r) {right=r;}
public void addSegment(Segment s) {segmentsStarting.add(s);}
public void calcH()
{
if (this.left!=null)
{
if (this.right != null)
{
if (this.left.h > this.right.h) this.h = this.left.h + 1;
else this.h = this.right.h + 1;
}
else this.h = this.left.h + 1;
}
else if (this.right!=null) this.h=this.right.h+1;
}
public void initialise(Segment segment)
{
if (NodeQ.isEmpty)
{
y=segment.yUpper;
x=segment.xUpper;
addSegment(segment);
setLeft(new NodeQ(segment.xLower, segment.yLower));
h=2;
NodeQ.isEmpty=false;
}
else
{
insert(segment.xUpper, segment.yUpper, true, segment);
insert(segment.xLower, segment.yLower, false, segment);
}
}
public void deepCopy(NodeQ Q)
{
this.x=Q.x;
this.y=Q.y;
this.segmentsStarting=Q.segmentsStarting;
if (Q.left==null)this.left=null;
else this.left=new NodeQ(Q.left);
if (Q.right==null) this.right=null;
else this.right=new NodeQ(Q.right);
}
public void insert(double abs, double ord, boolean isUpperEndpoint, Segment s)
{
if (y>ord || (y==ord && x<abs))
{
if (left==null)
{
left=new NodeQ(abs, ord);
if (isUpperEndpoint) addSegment(s);
}
else left.insert(abs, ord, isUpperEndpoint, s);
}
else
{
if (right==null)
{
right=new NodeQ(abs, ord);
if (isUpperEndpoint) addSegment(s);
}
else right.insert(abs, ord, isUpperEndpoint, s);
}
balancing();
}
public void leftRotation()
{
NodeQ tmp=new NodeQ(-1, -1);
tmp.deepCopy(this);
this.deepCopy(this.right);
if (this.left==null) tmp.right=null;
else tmp.right=new NodeQ(this.left);
this.left=new NodeQ(tmp);
tmp.calcH();
this.calcH();
}
public void rightRotation()
{
NodeQ tmp=new NodeQ(-1, -1);
tmp.deepCopy(this);
this.deepCopy(this.left);
if (this.right==null) tmp.left=null;
else tmp.left=new NodeQ(this.right);
this.right=new NodeQ(tmp);
tmp.calcH();
this.calcH();
}
public int calcBalance()
{
int bal=0;
if (left==null)
{
if (right!=null) bal=right.h;
}
else
{
if (right==null) bal=-left.h;
else bal=right.h-left.h;
}
return bal;
}
public void balancing()
{
int b=calcBalance();
if (b==2)
{
if (right.calcBalance()<0) right.rightRotation();
leftRotation();
}
else if (b==-2)
{
` if (left.calcBalance()>0) left.leftRotation();
rightRotation();
}
else calcH();
}
}
答案 0 :(得分:2)
你应该简单地避免复制节点;您可以通过分配左和右指针来平衡子树。
旋转函数应该将子树根作为参数并返回变换后的子树;旋转树木&#34;到位&#34;是一种主要的不必要的并发症。
答案 1 :(得分:0)
深度克隆的一种非常简单的方法是实现Serializable,然后序列化/反序列化对象(例如,到ByteArrayOutputStream)。