Skip to content

Commit 86563d1

Browse files
committed
optimize trees by eliminating recursion when possible
1 parent 0904d5a commit 86563d1

File tree

11 files changed

+808
-985
lines changed

11 files changed

+808
-985
lines changed

Advanced.Algorithms/DataStructures/Tree/FenwickTree.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ namespace Advanced.Algorithms.DataStructures
88
/// <typeparam name="T"></typeparam>
99
public class FenwickTree<T>
1010
{
11-
private int length => Tree.Length - 1;
12-
private T[] Tree;
11+
private int length => tree.Length - 1;
12+
private T[] tree;
1313

1414
/// <summary>
1515
/// add operation on generic type
@@ -29,23 +29,23 @@ public FenwickTree(T[] input, Func<T, T, T> sumOperation)
2929
}
3030

3131
this.sumOperation = sumOperation;
32-
Construct(input);
32+
construct(input);
3333
}
3434

3535
/// <summary>
3636
/// construct fenwick tree from input array
3737
/// </summary>
3838
/// <param name="input"></param>
39-
private void Construct(T[] input)
39+
private void construct(T[] input)
4040
{
41-
Tree = new T[input.Length + 1];
41+
tree = new T[input.Length + 1];
4242

4343
for (var i = 0; i < input.Length; i++)
4444
{
4545
var j = i + 1;
4646
while (j < input.Length)
4747
{
48-
Tree[j] = sumOperation(Tree[j], input[i]);
48+
tree[j] = sumOperation(tree[j], input[i]);
4949
j = getNextIndex(j);
5050
}
5151
}
@@ -70,7 +70,7 @@ public T GetPrefixSum(int endIndex)
7070

7171
while (currentIndex > 0)
7272
{
73-
sum = sumOperation(sum, Tree[currentIndex]);
73+
sum = sumOperation(sum, tree[currentIndex]);
7474
currentIndex = getParentIndex(currentIndex);
7575
}
7676

Advanced.Algorithms/DataStructures/Tree/IntervalTree.cs

Lines changed: 119 additions & 112 deletions
Large diffs are not rendered by default.

Advanced.Algorithms/DataStructures/Tree/RangeTree.cs

Lines changed: 38 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ public void Insert(T[] value)
5555
var currentTree = tree;
5656
//get all overlaps
5757
//and insert next dimension value to each overlapping node
58-
for (int i = 0; i < dimensions; i++)
58+
for (var i = 0; i < dimensions; i++)
5959
{
6060
currentTree = currentTree.Insert(value[i]).tree;
6161
}
@@ -102,8 +102,8 @@ private void DeleteRecursive(RangeTree<T> tree, T[] value, int currentDimension,
102102

103103
//delete node if next dimension has no elements
104104
//or when this is the last dimension and we found element
105-
if (found && ((currentDimension + 1 == dimensions)
106-
|| (node.tree.Count == 0 && currentDimension + 1 < dimensions)))
105+
if (node != null && found && (currentDimension + 1 == dimensions
106+
|| node.tree.Count == 0 && currentDimension + 1 < dimensions))
107107
{
108108
tree.Delete(value[currentDimension]);
109109
}
@@ -121,7 +121,7 @@ public List<T[]> GetInRange(T[] start, T[] end)
121121
validateDimensions(start);
122122
validateDimensions(end);
123123

124-
return GetInRange(tree, start, end, 0);
124+
return getInRange(tree, start, end, 0);
125125

126126
}
127127

@@ -133,7 +133,7 @@ public List<T[]> GetInRange(T[] start, T[] end)
133133
/// <param name="end"></param>
134134
/// <param name="dimension"></param>
135135
/// <returns></returns>
136-
private List<T[]> GetInRange(
136+
private List<T[]> getInRange(
137137
RangeTree<T> currentTree,
138138
T[] start, T[] end, int dimension)
139139
{
@@ -158,7 +158,7 @@ private List<T[]> GetInRange(
158158

159159
foreach (var node in nodes)
160160
{
161-
var nextDimResult = GetInRange(node.tree, start, end, dimension + 1);
161+
var nextDimResult = getInRange(node.tree, start, end, dimension + 1);
162162

163163
foreach (var nextResult in nextDimResult)
164164
{
@@ -176,15 +176,17 @@ private List<T[]> GetInRange(
176176
/// validate dimensions for point length
177177
/// </summary>
178178
/// <param name="start"></param>
179-
/// <param name="end"></param>
180179
private void validateDimensions(T[] start)
181180
{
182-
if (start.Length != dimensions)
181+
if (start == null)
183182
{
184-
throw new Exception(string.Format("Expecting {0} points.",
185-
dimensions));
183+
throw new ArgumentNullException(nameof(start));
186184
}
187185

186+
if (start.Length != dimensions)
187+
{
188+
throw new Exception($"Expecting {dimensions} points.");
189+
}
188190
}
189191
}
190192

@@ -221,25 +223,27 @@ internal void Delete(T value)
221223

222224
internal List<RangeTreeNode<T>> GetInRange(T start, T end)
223225
{
224-
return GetInRange(new List<RangeTreeNode<T>>(),
226+
return getInRange(new List<RangeTreeNode<T>>(),
225227
new System.Collections.Generic.Dictionary<RedBlackTreeNode<RangeTreeNode<T>>, bool>(),
226228
tree.Root, start, end);
227229
}
228230

229-
private List<RangeTreeNode<T>> GetInRange(List<RangeTreeNode<T>> result, System.Collections.Generic.Dictionary<RedBlackTreeNode<RangeTreeNode<T>>, bool> visited,
231+
private List<RangeTreeNode<T>> getInRange(List<RangeTreeNode<T>> result, System.Collections.Generic.Dictionary<RedBlackTreeNode<RangeTreeNode<T>>, bool> visited,
230232
RedBlackTreeNode<RangeTreeNode<T>> currentNode,
231233
T start, T end)
232234
{
233235

234236
if (currentNode.IsLeaf)
235237
{
236238
//start is less than current node
237-
if (InRange(currentNode, start, end))
239+
if (!inRange(currentNode, start, end))
238240
{
239-
foreach (var v in currentNode.Values)
240-
{
241-
result.Add(v);
242-
}
241+
return result;
242+
}
243+
244+
foreach (var v in currentNode.Values)
245+
{
246+
result.Add(v);
243247
}
244248
}
245249
//if start is less than current
@@ -250,13 +254,13 @@ private List<RangeTreeNode<T>> GetInRange(List<RangeTreeNode<T>> result, System.
250254
{
251255
if (currentNode.Left != null)
252256
{
253-
GetInRange(result, visited, currentNode.Left, start, end);
257+
getInRange(result, visited, currentNode.Left, start, end);
254258
}
255259

256260

257261
//start is less than current node
258262
if (!visited.ContainsKey(currentNode)
259-
&& InRange(currentNode, start, end))
263+
&& inRange(currentNode, start, end))
260264
{
261265
foreach (var v in currentNode.Values)
262266
{
@@ -269,24 +273,29 @@ private List<RangeTreeNode<T>> GetInRange(List<RangeTreeNode<T>> result, System.
269273
//if start is greater than current
270274
//and end is greater than current
271275
//move right
272-
if (end.CompareTo(currentNode.Value.Data) >= 0)
276+
if (end.CompareTo(currentNode.Value.Data) < 0)
277+
{
278+
return result;
279+
}
280+
273281
{
274282
if (currentNode.Right != null)
275283
{
276-
GetInRange(result, visited, currentNode.Right, start, end);
284+
getInRange(result, visited, currentNode.Right, start, end);
277285
}
278286

279287
//start is less than current node
280-
if (!visited.ContainsKey(currentNode)
281-
&& InRange(currentNode, start, end))
288+
if (visited.ContainsKey(currentNode) || !inRange(currentNode, start, end))
282289
{
283-
foreach (var v in currentNode.Values)
284-
{
285-
result.Add(v);
286-
}
290+
return result;
291+
}
287292

288-
visited.Add(currentNode, false);
293+
foreach (var v in currentNode.Values)
294+
{
295+
result.Add(v);
289296
}
297+
298+
visited.Add(currentNode, false);
290299
}
291300
}
292301

@@ -300,7 +309,7 @@ private List<RangeTreeNode<T>> GetInRange(List<RangeTreeNode<T>> result, System.
300309
/// <param name="start"></param>
301310
/// <param name="end"></param>
302311
/// <returns></returns>
303-
private bool InRange(RedBlackTreeNode<RangeTreeNode<T>> currentNode, T start, T end)
312+
private bool inRange(RedBlackTreeNode<RangeTreeNode<T>> currentNode, T start, T end)
304313
{
305314
//start is less than current & end is greater than current
306315
return start.CompareTo(currentNode.Value.Data) <= 0

0 commit comments

Comments
 (0)