提交 3026acf9 编写于 作者: C Cyrus Najmabadi

Make interval tree construction always 'in-place'

上级 14a02817
...@@ -32,7 +32,7 @@ public ContextIntervalTree(IIntervalIntrospector<T> introspector) ...@@ -32,7 +32,7 @@ public ContextIntervalTree(IIntervalIntrospector<T> introspector)
public void AddIntervalInPlace(T value) public void AddIntervalInPlace(T value)
{ {
var newNode = new Node(Introspector, value); var newNode = new Node(Introspector, value);
this.root = Insert(root, newNode, Introspector, inPlace: true); this.root = Insert(root, newNode, Introspector);
} }
public T GetSmallestEdgeExclusivelyContainingInterval(int start, int length) public T GetSmallestEdgeExclusivelyContainingInterval(int start, int length)
......
...@@ -61,11 +61,6 @@ internal void SetLeftRight(Node left, Node right, IIntervalIntrospector<T> intro ...@@ -61,11 +61,6 @@ internal void SetLeftRight(Node left, Node right, IIntervalIntrospector<T> intro
} }
} }
internal Node With(Node left, Node right, IIntervalIntrospector<T> introspector)
{
return new Node(introspector, this.Value, left, right);
}
// Sample: // Sample:
// 1 2 // 1 2
// / \ / \ // / \ / \
...@@ -74,25 +69,13 @@ internal Node With(Node left, Node right, IIntervalIntrospector<T> introspector) ...@@ -74,25 +69,13 @@ internal Node With(Node left, Node right, IIntervalIntrospector<T> introspector)
// 3 c a b c d // 3 c a b c d
// / \ // / \
// a b // a b
internal Node RightRotation(bool inPlace, IIntervalIntrospector<T> introspector) internal Node RightRotation(IIntervalIntrospector<T> introspector)
{ {
if (inPlace) var oldLeft = this.Left;
{ this.SetLeftRight(this.Left.Right, this.Right, introspector);
var oldLeft = this.Left; oldLeft.SetLeftRight(oldLeft.Left, this, introspector);
this.SetLeftRight(this.Left.Right, this.Right, introspector);
oldLeft.SetLeftRight(oldLeft.Left, this, introspector);
return oldLeft; return oldLeft;
}
else
{
var newLeft = this.Left.Left;
var newRight = this.With(
this.Left.Right,
this.Right,
introspector);
return this.Left.With(newLeft, newRight, introspector);
}
} }
// Sample: // Sample:
...@@ -103,24 +86,12 @@ internal Node RightRotation(bool inPlace, IIntervalIntrospector<T> introspector) ...@@ -103,24 +86,12 @@ internal Node RightRotation(bool inPlace, IIntervalIntrospector<T> introspector)
// b 3 a b c d // b 3 a b c d
// / \ // / \
// c d // c d
internal Node LeftRotation(bool inPlace, IIntervalIntrospector<T> introspector) internal Node LeftRotation(IIntervalIntrospector<T> introspector)
{ {
if (inPlace) var oldRight = this.Right;
{ this.SetLeftRight(this.Left, this.Right.Left, introspector);
var oldRight = this.Right; oldRight.SetLeftRight(this, oldRight.Right, introspector);
this.SetLeftRight(this.Left, this.Right.Left, introspector); return oldRight;
oldRight.SetLeftRight(this, oldRight.Right, introspector);
return oldRight;
}
else
{
var newLeft = this.With(
this.Left,
this.Right.Left,
introspector);
var newRight = this.Right.Right;
return this.Right.With(newLeft, newRight, introspector);
}
} }
// Sample: // Sample:
...@@ -131,27 +102,16 @@ internal Node LeftRotation(bool inPlace, IIntervalIntrospector<T> introspector) ...@@ -131,27 +102,16 @@ internal Node LeftRotation(bool inPlace, IIntervalIntrospector<T> introspector)
// 3 d b 2 a b c d // 3 d b 2 a b c d
// / \ / \ // / \ / \
// b c c d // b c c d
internal Node InnerRightOuterLeftRotation(bool inPlace, IIntervalIntrospector<T> introspector) internal Node InnerRightOuterLeftRotation(IIntervalIntrospector<T> introspector)
{ {
if (inPlace) var newTop = this.Right.Left;
{ var oldRight = this.Right;
var newTop = this.Right.Left;
var oldRight = this.Right;
this.SetLeftRight(this.Left, this.Right.Left.Left, introspector); this.SetLeftRight(this.Left, this.Right.Left.Left, introspector);
oldRight.SetLeftRight(oldRight.Left.Right, oldRight.Right, introspector); oldRight.SetLeftRight(oldRight.Left.Right, oldRight.Right, introspector);
newTop.SetLeftRight(this, oldRight, introspector); newTop.SetLeftRight(this, oldRight, introspector);
return newTop; return newTop;
}
else
{
var temp = this.With(
this.Left,
this.Right.RightRotation(inPlace, introspector),
introspector);
return temp.LeftRotation(inPlace, introspector);
}
} }
// Sample: // Sample:
...@@ -162,27 +122,16 @@ internal Node InnerRightOuterLeftRotation(bool inPlace, IIntervalIntrospector<T> ...@@ -162,27 +122,16 @@ internal Node InnerRightOuterLeftRotation(bool inPlace, IIntervalIntrospector<T>
// a 3 2 c a b c d // a 3 2 c a b c d
// / \ / \ // / \ / \
// b c a b // b c a b
internal Node InnerLeftOuterRightRotation(bool inPlace, IIntervalIntrospector<T> introspector) internal Node InnerLeftOuterRightRotation(IIntervalIntrospector<T> introspector)
{ {
if (inPlace) var newTop = this.Left.Right;
{ var oldLeft = this.Left;
var newTop = this.Left.Right;
var oldLeft = this.Left;
this.SetLeftRight(this.Left.Right.Right, this.Right, introspector); this.SetLeftRight(this.Left.Right.Right, this.Right, introspector);
oldLeft.SetLeftRight(oldLeft.Left, oldLeft.Right.Left, introspector); oldLeft.SetLeftRight(oldLeft.Left, oldLeft.Right.Left, introspector);
newTop.SetLeftRight(oldLeft, this, introspector); newTop.SetLeftRight(oldLeft, this, introspector);
return newTop; return newTop;
}
else
{
var temp = this.With(
this.Left.LeftRotation(inPlace, introspector),
this.Right,
introspector);
return temp.RightRotation(inPlace, introspector);
}
} }
} }
} }
......
...@@ -38,7 +38,7 @@ public IntervalTree(IIntervalIntrospector<T> introspector, IEnumerable<T> values ...@@ -38,7 +38,7 @@ public IntervalTree(IIntervalIntrospector<T> introspector, IEnumerable<T> values
{ {
foreach (var value in values) foreach (var value in values)
{ {
root = Insert(root, new Node(introspector, value), introspector, inPlace: true); root = Insert(root, new Node(introspector, value), introspector);
} }
} }
...@@ -223,13 +223,13 @@ public bool IsEmpty() ...@@ -223,13 +223,13 @@ public bool IsEmpty()
return this.root == null; return this.root == null;
} }
protected static Node Insert(Node root, Node newNode, IIntervalIntrospector<T> introspector, bool inPlace) protected static Node Insert(Node root, Node newNode, IIntervalIntrospector<T> introspector)
{ {
var newNodeStart = introspector.GetStart(newNode.Value); var newNodeStart = introspector.GetStart(newNode.Value);
return Insert(root, newNode, newNodeStart, introspector, inPlace); return Insert(root, newNode, newNodeStart, introspector);
} }
private static Node Insert(Node root, Node newNode, int newNodeStart, IIntervalIntrospector<T> introspector, bool inPlace) private static Node Insert(Node root, Node newNode, int newNodeStart, IIntervalIntrospector<T> introspector)
{ {
if (root == null) if (root == null)
{ {
...@@ -240,30 +240,22 @@ private static Node Insert(Node root, Node newNode, int newNodeStart, IIntervalI ...@@ -240,30 +240,22 @@ private static Node Insert(Node root, Node newNode, int newNodeStart, IIntervalI
if (newNodeStart < introspector.GetStart(root.Value)) if (newNodeStart < introspector.GetStart(root.Value))
{ {
newLeft = Insert(root.Left, newNode, newNodeStart, introspector, inPlace); newLeft = Insert(root.Left, newNode, newNodeStart, introspector);
newRight = root.Right; newRight = root.Right;
} }
else else
{ {
newLeft = root.Left; newLeft = root.Left;
newRight = Insert(root.Right, newNode, newNodeStart, introspector, inPlace); newRight = Insert(root.Right, newNode, newNodeStart, introspector);
} }
Node newRoot; root.SetLeftRight(newLeft, newRight, introspector);
if (inPlace) var newRoot = root;
{
root.SetLeftRight(newLeft, newRight, introspector);
newRoot = root;
}
else
{
newRoot = new Node(introspector, root.Value, newLeft, newRight);
}
return Balance(newRoot, inPlace, introspector); return Balance(newRoot, introspector);
} }
private static Node Balance(Node node, bool inPlace, IIntervalIntrospector<T> introspector) private static Node Balance(Node node, IIntervalIntrospector<T> introspector)
{ {
int balanceFactor = BalanceFactor(node); int balanceFactor = BalanceFactor(node);
if (balanceFactor == -2) if (balanceFactor == -2)
...@@ -271,12 +263,12 @@ private static Node Balance(Node node, bool inPlace, IIntervalIntrospector<T> in ...@@ -271,12 +263,12 @@ private static Node Balance(Node node, bool inPlace, IIntervalIntrospector<T> in
int rightBalance = BalanceFactor(node.Right); int rightBalance = BalanceFactor(node.Right);
if (rightBalance == -1) if (rightBalance == -1)
{ {
return node.LeftRotation(inPlace, introspector); return node.LeftRotation(introspector);
} }
else else
{ {
Contract.Requires(rightBalance == 1); Contract.Requires(rightBalance == 1);
return node.InnerRightOuterLeftRotation(inPlace, introspector); return node.InnerRightOuterLeftRotation(introspector);
} }
} }
else if (balanceFactor == 2) else if (balanceFactor == 2)
...@@ -284,12 +276,12 @@ private static Node Balance(Node node, bool inPlace, IIntervalIntrospector<T> in ...@@ -284,12 +276,12 @@ private static Node Balance(Node node, bool inPlace, IIntervalIntrospector<T> in
int leftBalance = BalanceFactor(node.Left); int leftBalance = BalanceFactor(node.Left);
if (leftBalance == 1) if (leftBalance == 1)
{ {
return node.RightRotation(inPlace, introspector); return node.RightRotation(introspector);
} }
else else
{ {
Contract.Requires(leftBalance == -1); Contract.Requires(leftBalance == -1);
return node.InnerLeftOuterRightRotation(inPlace, introspector); return node.InnerLeftOuterRightRotation(introspector);
} }
} }
......
...@@ -32,7 +32,7 @@ public SimpleIntervalTree(IIntervalIntrospector<T> introspector, IEnumerable<T> ...@@ -32,7 +32,7 @@ public SimpleIntervalTree(IIntervalIntrospector<T> introspector, IEnumerable<T>
{ {
foreach (var value in values) foreach (var value in values)
{ {
root = Insert(root, new Node(introspector, value), introspector, inPlace: true); root = Insert(root, new Node(introspector, value), introspector);
} }
} }
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册