예제 #1
0
        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));
            }
        }
예제 #2
0
        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}");
            }
        }
예제 #3
0
        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);
        }