private static IEnumerable <int> Sets(Random rnd, ARRAY test) { for (var i = 0; i <= 32; i++) { var x = rnd.Next(); yield return(test.set(x)); Debug.Assert(test.get(x)); } }
static void Main(string[] args) { var test = new ARRAY(1); var reference = new HashSet <int>(); var rnd = new Random(); reference.Add(1); var ops = 0; foreach (var o in Sets(rnd, test)) { ops += o; Console.WriteLine($"{test.SetCount}: {o}, total {ops}, merges so far {ARRAY.MergeCount}"); } }
int upd() //пошаговое отложенное слияние двух массивов в один { var ops = 0; if (keyResult != null) { if (countLeft < len) { if (countRight < len) { if (keyLeft[countLeft] < keyRight[countRight]) //если текущий элемент 1-го подмассива меньше 2-го - вносим его { keyResult[countResult] = keyLeft[countLeft]; countResult++; countLeft++; ops++; MergeCount++; } else //если текущий элемент 2-го подмассива меньше 1-го - вносим его в массив слияния { keyResult[countResult] = keyRight[countRight]; countResult++; countRight++; ops++; MergeCount++; } } else //значит 2-й массив уже весь перемещён и необходимо добавить сл. элемент из первого подмассива { keyResult[countResult] = keyLeft[countLeft]; countResult++; countLeft++; ops++; MergeCount++; } } else { if (countRight < len) //значит 1-й массив уже весь перемещён - добавляем сл. элемент из второго подмассива { keyResult[countResult] = keyRight[countRight]; countResult++; countRight++; ops++; MergeCount++; } //в противном случае все элементы обоих массивов уже присутствуют в результирующем - ничего не делаем } if (countResult == len * 2) //Если после очередного шага слияние завершилось { if (nextLevel == null) { //Console.WriteLine("Allocating level..."); nextLevel = new ARRAY(len * 2); //Создаём сл. уровень, если он ещё не существует } ops += nextLevel.set(keyResult, len * 2); keyResult = null; keyLeft = null; keyRight = null; keyTemp = null; ops++; } } ops += nextLevel?.upd() ?? 0; return(ops); }