static void TestQuickSortAndMedian() { Random r = new Random(); List <ValueTuple <int, int> > list = new List <ValueTuple <int, int> >(); for (int i = 0; i < 100; i++) { int a = r.Next(1000); list.Add(new ValueTuple <int, int>(a, 1000 - a)); } var xMedian = list.Median(new XCoordinateComparer <int>()); var yMedian = list.Median(new YCoordinateComparer <int>()); var xSorted = QuickSort <int> .Sort(list, new XCoordinateComparer <int>()); var ySorted = QuickSort <int> .Sort(list, new YCoordinateComparer <int>()); }
/// <summary> /// Finds median by quicksorting. /// </summary> /// <typeparam name="T">Type of ValueTuple.</typeparam> /// <param name="list">List of ValueTuples.</param> /// <param name="comparer">ValueTuple comparer to be used.</param> /// <returns>Median ValueTuple.</returns> public static ValueTuple <T, T> Median <T>(this List <ValueTuple <T, T> > list, IComparer <ValueTuple <T, T> > comparer) { var sorted = QuickSort <T> .Sort(list, comparer); return(sorted[sorted.Count / 2]); }
/// <summary> /// Inserts a new value to tree. /// </summary> /// <param name="newvalue">2D point to be inserted</param> /// <param name="currentCoordinate">Current coordinate to navigate by</param> public void Insert(ValueTuple <TValue, TValue> newvalue, int currentCoordinate) { // for tree validity check //SaveLastState(OperationType.INSERT); lastOpVisitedNodes = 0; if (Root == null) { lastOpVisitedNodes = 1; Root = new RangeTreeNode <TValue>(newvalue, Alpha, currentCoordinate); return; } var comparer = (currentCoordinate == 0) ? xComparer : yComparer; var currentNode = Root; var parent = Root; // find a place for new leaf while (currentNode != null) { lastOpVisitedNodes++; parent = currentNode; if (currentCoordinate == 0) { currentNode.OtherDimensionSubtree.Insert(newvalue, 1); } // greater if (comparer.Compare(newvalue, currentNode.Value) > 0) { currentNode.SubtreeNodesCount++; currentNode = currentNode.Right; } // lesser else if (comparer.Compare(newvalue, currentNode.Value) < 0) { currentNode.SubtreeNodesCount++; currentNode = currentNode.Left; } // equal else { currentNode.AddMiddleSon(new RangeTreeNode <TValue>(newvalue, Alpha, currentCoordinate)); // we are done here, this cannot break the invariant return; } } // add the new leaf RangeTreeNode <TValue> leaf = new RangeTreeNode <TValue>(newvalue, Alpha, currentCoordinate); if (comparer.Compare(parent.Value, newvalue) > 0) { parent.SetLeftSon(leaf); } else { parent.SetRightSon(leaf); } parent.SubtreeNodesCount--; // rebuild the unbalanced trees currentNode = parent; while (currentNode != null) { if (!currentNode.IsBalanced()) { var nodes = QuickSort <TValue> .Sort(currentNode.GetSubtreeValuesInOrder(), yComparer); var rebuild = Build(nodes, currentCoordinate); // for x and y tree lastOpVisitedNodes += (rebuild.SubtreeNodesCount); // we rebuit entire tree if (currentNode.Parent == null) { Root = rebuild; currentNode = rebuild; } else { if (comparer.Compare(currentNode.Parent.Value, rebuild.Value) > 0) { currentNode.Parent.SetLeftSon(rebuild); } else { currentNode.Parent.SetRightSon(rebuild); } } } currentNode = currentNode.Parent; } }