提交 dc968531 编写于 作者: C CyrusNajmabadi

Merge pull request #3608 from CyrusNajmabadi/sortedIntervalTree

Iterate elements of an interval tree in sorted order.
......@@ -153,44 +153,6 @@ public void TestOverlappingStart()
}
}
[Fact]
public void TestRightRotation()
{
var nodes = new[]
{
Tuple.Create(8, 1, "a"),
Tuple.Create(10, 1, "b"),
Tuple.Create(4, 1, "c"),
Tuple.Create(6, 1, "d"),
Tuple.Create(0, 1, "e"),
Tuple.Create(2, 1, "f")
};
foreach (var tree in CreateTrees(nodes))
{
Assert.True(tree.Select(t => t.Item3).SequenceEqual(
List("c", "e", "f", "a", "d", "b")));
}
}
[Fact]
public void InnerLeftOuterRightRotation()
{
var nodes = new[]
{
Tuple.Create(8, 1, "a"),
Tuple.Create(10, 1, "b"),
Tuple.Create(2, 1, "c"),
Tuple.Create(0, 1, "e"),
Tuple.Create(4, 1, "d"),
Tuple.Create(6, 1, "f")
};
foreach (var tree in CreateTrees(nodes))
{
Assert.True(tree.Select(t => t.Item3).SequenceEqual(
List("d", "c", "e", "a", "f", "b")));
}
}
[Fact]
public void TestOverlappingEnd()
{
......@@ -307,6 +269,70 @@ public void TestEmptySpanAtStart()
Assert.Equal(1, tree.Count());
}
private class Int32Introspector: IIntervalIntrospector<int>
{
public static Int32Introspector Instance = new Int32Introspector();
public int GetLength(int value)
{
return 0;
}
public int GetStart(int value)
{
return value;
}
}
private IntervalTree<int> CreateIntTree(params int[] values)
{
return new IntervalTree<int>(Int32Introspector.Instance, values);
}
[Fact]
public void TestSortedEnumerable1()
{
var tree = new IntervalTree<int>(Int32Introspector.Instance, new[] { 0, 0, 0 });
Assert.Equal(CreateIntTree(0, 0, 0), new[] { 0, 0, 0 });
Assert.Equal(CreateIntTree(0, 0, 1), new[] { 0, 0, 1 });
Assert.Equal(CreateIntTree(0, 0, 2), new[] { 0, 0, 2 });
Assert.Equal(CreateIntTree(0, 1, 0), new[] { 0, 0, 1 });
Assert.Equal(CreateIntTree(0, 1, 1), new[] { 0, 1, 1 });
Assert.Equal(CreateIntTree(0, 1, 2), new[] { 0, 1, 2 });
Assert.Equal(CreateIntTree(0, 2, 0), new[] { 0, 0, 2 });
Assert.Equal(CreateIntTree(0, 2, 1), new[] { 0, 1, 2 });
Assert.Equal(CreateIntTree(0, 2, 2), new[] { 0, 2, 2 });
Assert.Equal(CreateIntTree(1, 0, 0), new[] { 0, 0, 1 });
Assert.Equal(CreateIntTree(1, 0, 1), new[] { 0, 1, 1 });
Assert.Equal(CreateIntTree(1, 0, 2), new[] { 0, 1, 2 });
Assert.Equal(CreateIntTree(1, 1, 0), new[] { 0, 1, 1 });
Assert.Equal(CreateIntTree(1, 1, 1), new[] { 1, 1, 1 });
Assert.Equal(CreateIntTree(1, 1, 2), new[] { 1, 1, 2 });
Assert.Equal(CreateIntTree(1, 2, 0), new[] { 0, 1, 2 });
Assert.Equal(CreateIntTree(1, 2, 1), new[] { 1, 1, 2 });
Assert.Equal(CreateIntTree(1, 2, 2), new[] { 1, 2, 2 });
Assert.Equal(CreateIntTree(2, 0, 0), new[] { 0, 0, 2 });
Assert.Equal(CreateIntTree(2, 0, 1), new[] { 0, 1, 2 });
Assert.Equal(CreateIntTree(2, 0, 2), new[] { 0, 2, 2 });
Assert.Equal(CreateIntTree(2, 1, 0), new[] { 0, 1, 2 });
Assert.Equal(CreateIntTree(2, 1, 1), new[] { 1, 1, 2 });
Assert.Equal(CreateIntTree(2, 1, 2), new[] { 1, 2, 2 });
Assert.Equal(CreateIntTree(2, 2, 0), new[] { 0, 2, 2 });
Assert.Equal(CreateIntTree(2, 2, 1), new[] { 1, 2, 2 });
Assert.Equal(CreateIntTree(2, 2, 2), new[] { 2, 2, 2 });
}
[Fact]
public void TestSortedEnumerable2()
{
var tree = new IntervalTree<int>(Int32Introspector.Instance, new[] { 1, 0 });
Assert.Equal(tree, new[] { 0, 1 });
}
private static void TestOverlapsAndIntersects(IList<Tuple<int, int, string>> spans)
{
foreach (var tree in CreateTrees(spans))
......
......@@ -309,17 +309,28 @@ public IEnumerator<T> GetEnumerator()
yield break;
}
var candidates = new Stack<Node>();
candidates.Push(root);
// The bool indicates if this is the first time we are seeing the node.
var candidates = new Stack<ValueTuple<Node,bool>>();
candidates.Push(ValueTuple.Create(root, true));
while (candidates.Count != 0)
{
var current = candidates.Pop();
if (current != null)
var currentTuple = candidates.Pop();
var currentNode = currentTuple.Item1;
if (currentNode != null)
{
candidates.Push(current.Right);
candidates.Push(current.Left);
yield return current.Value;
if (currentTuple.Item2)
{
// First time seeing this node. Mark that we've been seen and recurse
// down the left side. The next time we see this node we'll yield it
// out.
candidates.Push(ValueTuple.Create(currentNode.Right, true));
candidates.Push(ValueTuple.Create(currentNode, false));
candidates.Push(ValueTuple.Create(currentNode.Left, true));
}
else
{
yield return currentNode.Value;
}
}
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册