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

Make interval tree construction always 'in-place'

上级 14a02817
......@@ -32,7 +32,7 @@ public ContextIntervalTree(IIntervalIntrospector<T> introspector)
public void AddIntervalInPlace(T 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)
......
......@@ -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:
// 1 2
// / \ / \
......@@ -74,25 +69,13 @@ internal Node With(Node left, Node right, IIntervalIntrospector<T> introspector)
// 3 c a b c d
// / \
// 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);
oldLeft.SetLeftRight(oldLeft.Left, this, introspector);
var oldLeft = this.Left;
this.SetLeftRight(this.Left.Right, this.Right, introspector);
oldLeft.SetLeftRight(oldLeft.Left, this, introspector);
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);
}
return oldLeft;
}
// Sample:
......@@ -103,24 +86,12 @@ internal Node RightRotation(bool inPlace, IIntervalIntrospector<T> introspector)
// b 3 a b 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);
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);
}
var oldRight = this.Right;
this.SetLeftRight(this.Left, this.Right.Left, introspector);
oldRight.SetLeftRight(this, oldRight.Right, introspector);
return oldRight;
}
// Sample:
......@@ -131,27 +102,16 @@ internal Node LeftRotation(bool inPlace, IIntervalIntrospector<T> introspector)
// 3 d b 2 a b 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);
oldRight.SetLeftRight(oldRight.Left.Right, oldRight.Right, introspector);
newTop.SetLeftRight(this, oldRight, introspector);
this.SetLeftRight(this.Left, this.Right.Left.Left, introspector);
oldRight.SetLeftRight(oldRight.Left.Right, oldRight.Right, introspector);
newTop.SetLeftRight(this, oldRight, introspector);
return newTop;
}
else
{
var temp = this.With(
this.Left,
this.Right.RightRotation(inPlace, introspector),
introspector);
return temp.LeftRotation(inPlace, introspector);
}
return newTop;
}
// Sample:
......@@ -162,27 +122,16 @@ internal Node InnerRightOuterLeftRotation(bool inPlace, IIntervalIntrospector<T>
// a 3 2 c a b c d
// / \ / \
// 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);
oldLeft.SetLeftRight(oldLeft.Left, oldLeft.Right.Left, introspector);
newTop.SetLeftRight(oldLeft, this, introspector);
this.SetLeftRight(this.Left.Right.Right, this.Right, introspector);
oldLeft.SetLeftRight(oldLeft.Left, oldLeft.Right.Left, introspector);
newTop.SetLeftRight(oldLeft, this, introspector);
return newTop;
}
else
{
var temp = this.With(
this.Left.LeftRotation(inPlace, introspector),
this.Right,
introspector);
return temp.RightRotation(inPlace, introspector);
}
return newTop;
}
}
}
......
......@@ -38,7 +38,7 @@ public IntervalTree(IIntervalIntrospector<T> introspector, IEnumerable<T> 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()
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);
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)
{
......@@ -240,30 +240,22 @@ private static Node Insert(Node root, Node newNode, int newNodeStart, IIntervalI
if (newNodeStart < introspector.GetStart(root.Value))
{
newLeft = Insert(root.Left, newNode, newNodeStart, introspector, inPlace);
newLeft = Insert(root.Left, newNode, newNodeStart, introspector);
newRight = root.Right;
}
else
{
newLeft = root.Left;
newRight = Insert(root.Right, newNode, newNodeStart, introspector, inPlace);
newRight = Insert(root.Right, newNode, newNodeStart, introspector);
}
Node newRoot;
if (inPlace)
{
root.SetLeftRight(newLeft, newRight, introspector);
newRoot = root;
}
else
{
newRoot = new Node(introspector, root.Value, newLeft, newRight);
}
root.SetLeftRight(newLeft, newRight, introspector);
var newRoot = root;
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);
if (balanceFactor == -2)
......@@ -271,12 +263,12 @@ private static Node Balance(Node node, bool inPlace, IIntervalIntrospector<T> in
int rightBalance = BalanceFactor(node.Right);
if (rightBalance == -1)
{
return node.LeftRotation(inPlace, introspector);
return node.LeftRotation(introspector);
}
else
{
Contract.Requires(rightBalance == 1);
return node.InnerRightOuterLeftRotation(inPlace, introspector);
return node.InnerRightOuterLeftRotation(introspector);
}
}
else if (balanceFactor == 2)
......@@ -284,12 +276,12 @@ private static Node Balance(Node node, bool inPlace, IIntervalIntrospector<T> in
int leftBalance = BalanceFactor(node.Left);
if (leftBalance == 1)
{
return node.RightRotation(inPlace, introspector);
return node.RightRotation(introspector);
}
else
{
Contract.Requires(leftBalance == -1);
return node.InnerLeftOuterRightRotation(inPlace, introspector);
return node.InnerLeftOuterRightRotation(introspector);
}
}
......
......@@ -32,7 +32,7 @@ public SimpleIntervalTree(IIntervalIntrospector<T> introspector, IEnumerable<T>
{
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.
先完成此消息的编辑!
想要评论请 注册