private static void CheckSortingOrder(Element[] sortedArray, Element[] originalArray)
        {
            /* 1. Проверка за наредба във възходящ ред */
            for (int i = 0; i < sortedArray.Length - 1; i++)
            {
                if (sortedArray[i].Key > sortedArray[i + 1].Key)
                {
                    throw new InvalidOperationException("Array is not sorted!");
                }
            }

            /* 2. Проверка за пермутация на изходните елементи */
            bool[] found = new bool[sortedArray.Length];
            for (int i = 0; i < sortedArray.Length; i++)
            {
                int j;
                for (j = 0; j < sortedArray.Length; j++)
                {
                    if (!found[j] && sortedArray[i].Equals(originalArray[j]))
                    {
                        found[j] = true;
                        break;
                    }
                }

                if (j >= sortedArray.Length)
                {
                    throw new InvalidOperationException("No element found");
                }
            }
        }
        private static void CombSort(Element[] array)
        {
            int n = array.Length;
            int gap = array.Length, s;
            do
            {
                s = 0;
                gap = (int)(gap / 1.3);
                if (gap < 1)
                {
                    gap = 1;
                }

                for (int i = 0; i < n - gap; i++)
                {
                    int j = i + gap;
                    if (array[i].Key > array[j].Key)
                    {
                        Swap(ref array[i], ref array[j]);
                        s++;
                    }
                }
            }
            while (s != 0 || gap == 0);
        }
        private static void Check(Element[] array, Element[] coppiedArray)
        {
            /* 1. Проверка за наредба във възходящ ред */
            for (int i = 0; i < array.Length - 1; i++)
            {
                Debug.Assert(array[i].Key <= array[i + 1].Key, "Wrong order");
            }

            /* 2. Проверка за пермутация на изходните елементи */
            bool[] found = new bool[array.Length];
            for (int i = 0; i < array.Length; i++)
            {
                int j;
                for (j = 0; j < array.Length; j++)
                {
                    if (!found[j] && array[i].Equals(coppiedArray[j]))
                    {
                        found[j] = true;
                        break;
                    }
                }

                Debug.Assert(j < array.Length, "No element found"); /* Пропада, ако не е намерен съответен */
            }
        }
        public static void CombSort(Element[] array)
        {
            if (array == null)
            {
                throw new ArgumentNullException(
                    nameof(array),
                    "Input array must not be null");
            }

            int n = array.Length;
            int gap = array.Length, s;
            do
            {
                s = 0;
                gap = (int)(gap / 1.3);
                if (gap < 1)
                {
                    gap = 1;
                }

                for (int i = 0; i < n - gap; i++)
                {
                    int j = i + gap;
                    if (array[i].Key > array[j].Key)
                    {
                        Swap(ref array[i], ref array[j]);
                        s++;
                    }
                }
            }
            while (s != 0 || gap == 0);
        }
        public void CombSortEmptyElementsShouldNotSort()
        {
            const int MaxValue = 0;

            Element[] elements = new Element[MaxValue];
            CombSorter.CombSort(elements);
            CheckSortingOrder(elements, elements);
        }
 private static void Initialize(Element[] array)
 {
     int n = array.Length;
     for (int i = 0; i < n; i++)
     {
         array[i].Key = Rand.Next() % n;
     }
 }
        private static void Print(Element[] array)
        {
            for (int i = 0; i < array.Length; i++)
            {
                Console.Write("{0} ", array[i].Key);
            }

            Console.WriteLine();
            Console.WriteLine();
        }
        internal static void Main()
        {
            Element[] array = new Element[MaxValue];
            Element[] saveArray = new Element[MaxValue];
            Initialize(array);
            Array.Copy(array, saveArray, array.Length); /* Запазва се копие на масива */
            Console.WriteLine("Масивът преди сортирането");
            Print(array);
            CombSort(array);
            Console.WriteLine("Масивът след сортирането");
            Print(array);

            Check(array, saveArray);
        }
        public void CombRandomElementsSholdSortCorrectly()
        {
            const int MaxValue = 100;
            const int TestsCount = 100;

            for (int i = 0; i < TestsCount; i++)
            {
                Element[] elements = new Element[MaxValue];
                Element[] saveArray = new Element[MaxValue];
                CombSorter.Initialize(elements);
                Array.Copy(elements, saveArray, elements.Length);
                CombSorter.CombSort(elements);

                CheckSortingOrder(elements, saveArray);
            }
        }
 private static void Swap(ref Element element1, ref Element element2)
 {
     Element tempElement = element1;
     element1 = element2;
     element2 = tempElement;
 }