//Merges all threads together
        public static void MergeThreads(int[] array, int count, int[] parts, string name, Stopwatch watch)
        {
            //we always merge the sorted block at the beginning with next block
            //the first block is getting bigger with each cycle
            for (int i = 0; i < count - 1; i++)
            {
                int[] temp = new int[array.Length];
                Array.Copy(array, temp, array.Length);
                Merge(array, temp, 0, parts[i], parts[i + 1]);

                //after each merge, generate a svg image showing current progress
                SVGgenerate.GenerateSVG(name, count, cnt++, 0, 0, array, watch.ElapsedTicks);
            }
        }
        //Mergesort algorithm implementation
        //Sorts with the idea, that two sorted arrays can be easily merged together
        public void Sort(int[] array, int start, int end, bool threaded)
        {
            //create a copy of an array to measure time at first sorting
            int[] mergearray;

            if (threaded)
            {
                mergearray = array;
            }
            else
            {
                mergearray = new int[array.Length];
                Array.Copy(array, mergearray, array.Length);
            }

            //a list for storing measured time
            List <long> time = new List <long>();

            //start measuring time from the beginning of sorting
            var watch = new Stopwatch();

            watch.Start();

            time.Add(watch.ElapsedTicks);

            //run mergesort recursively
            MergeSort(mergearray, start, end, false, watch, time);

            watch.Stop();

            if (threaded)
            {
                return;
            }

            //run a second sorting, this time the duration is already measured, so we can create frames during the run

            frame       = 0;
            comparisons = 0;
            accesses    = 0;

            SVGgenerate.GenerateSVG("mergesort", 0, frame, comparisons, accesses, array, time[frame]);

            //run mergesort recursively
            MergeSort(array, start, end, true, watch, time);

            InfoFile.CreateInfoFile("mergesort", array.Length, time.Last(), comparisons, accesses, 0);
        }
        //auxiliary method for quicksort, finds a pivot
        public int FindPivot(int[] array, int left, int right, List <long> time, Stopwatch watch, bool draw)
        {
            access++;
            //begin at the first element of parted array
            int pivot = array[left];

            //until a pivot is found and a value is returned, repeat
            while (true)
            {
                comparison = comparison + 3;
                access     = access + 2;
                while (array[left] < pivot)
                {
                    left++;
                }

                while (array[right] > pivot)
                {
                    right--;
                }

                //if left is smaller than right, swap them
                if (left < right)
                {
                    int temp = array[left];
                    array[left]  = array[right];
                    array[right] = temp;

                    //decide whether to save time into a list of times in case of first run or draw an image in case of second run
                    if (draw)
                    {
                        frame++;
                        SVGgenerate.GenerateSVG("quicksort", 0, frame, comparison, access, array, time[frame]);
                    }
                    else
                    {
                        time.Add(watch.ElapsedTicks);
                    }
                }

                //if swapping isn't needed, pivot is found, return a value
                else
                {
                    return(right);
                }
            }
        }
        //recursively splits an array into two parts and merges two sorted parts
        public static void MergeSort(int[] array, int start, int end, bool draw, Stopwatch watch, List <long> time)
        {
            if (start < end)
            {
                int mid = (start + end) / 2;
                MergeSort(array, start, mid, draw, watch, time);
                MergeSort(array, mid + 1, end, draw, watch, time);
                Merge(array, start, mid, end);

                if (draw)
                {
                    frame++;
                    SVGgenerate.GenerateSVG("mergesort", 0, frame, comparisons, accesses, array, time[frame]);
                }
                else
                {
                    time.Add(watch.ElapsedTicks);
                }
            }
        }
Example #5
0
        //Bucketsort algorithm implementation
        //It doesn't use any comparing, this algorithm sorts an array by putting numbers in buckets according to the decimal value
        public void Sort(int[] array, int start, int end, bool threaded)
        {
            int buckets = array.Length;

            //in case of two steps sorting for singlethreaded run, we copy the contents of an array to an auxiliary one
            int[] bucketarray;

            if (threaded)
            {
                bucketarray = array;
            }
            else
            {
                bucketarray = new int[array.Length];
                Array.Copy(array, bucketarray, array.Length);
            }

            //a list for storing measured time
            List <long> time = new List <long>();

            int frame       = 0;
            int comparisons = 0;
            int accesses    = 0;

            //start measuring time from the beginning of sorting
            var watch = new Stopwatch();

            watch.Start();

            time.Add(watch.ElapsedTicks);

            //ten buckets for numbers 0..9
            Queue <int>[] sub = new Queue <int> [10];

            //initialize queues
            for (int i = 0; i < 10; i++)
            {
                sub[i] = new Queue <int>();
            }

            int k, l, m;

            //for each decimal of maximum number in the array
            for (int j = 10; j <= (buckets * 10); j = (j * 10))
            {
                k = start;
                //put every number in according bucket
                while (k <= end)
                {
                    l = (bucketarray[k]) % j;
                    m = l % (j / 10);
                    l = (l - m) / (j / 10);
                    sub[l].Enqueue(bucketarray[k]);
                    k++;
                }

                //starting index of an array
                k = start;
                //go through all ten buckets
                for (int i = 0; i < 10; i++)
                {
                    //until the current buckets isn't empty, pop an element and put it into an array
                    while (sub[i].Count != 0)
                    {
                        bucketarray[k] = sub[i].Dequeue();
                        //increment the counter
                        k++;
                        time.Add(watch.ElapsedTicks);
                    }
                }
            }

            //in case of multithreaded sorting, we sorted required part of an array and can exit
            if (threaded)
            {
                return;
            }

            watch.Stop();

            //run a second sorting, this time the duration is already measured, so we can create frames during the run

            SVGgenerate.GenerateSVG("bucketsort", 0, frame, comparisons, accesses, array, time[frame]);

            //ten buckets for numbers 0..9
            Queue <int>[] secsub = new Queue <int> [10];

            //initialize queues
            for (int i = 0; i < 10; i++)
            {
                accesses++;
                secsub[i] = new Queue <int>();
            }


            //for each decimal of maximum number in the array
            for (int j = 10; j <= (buckets * 10); j = (j * 10))
            {
                k = 0;
                //put every number in according bucket
                while (k < array.Length)
                {
                    accesses++;
                    l = (array[k]) % j;
                    m = l % (j / 10);
                    l = (l - m) / (j / 10);
                    accesses++;
                    secsub[l].Enqueue(array[k]);
                    k++;
                }

                //starting index of an array
                k = 0;
                //go through all ten buckets
                for (int i = 0; i < 10; i++)
                {
                    //until the current buckets isn't empty, pop an element and put it into an array
                    while (secsub[i].Count != 0)
                    {
                        accesses++;
                        array[k] = secsub[i].Dequeue();
                        //increment the counter
                        k++;
                        frame++;
                        SVGgenerate.GenerateSVG("bucketsort", 0, frame, comparisons, accesses, array, time[frame]);
                    }
                }
            }

            //before we exit, we create an info file summarizing the result of an algorithm
            InfoFile.CreateInfoFile("bucketsort", array.Length, time.Last(), comparisons, accesses, 0);
        }
        //Shakersort algorithm implementation
        //Also sometimes named cocktailsort, it is advanced bubblesort, that returns when it reaches an end of the array.
        public void Sort(int[] array, int start, int end, bool threaded)
        {
            //in case of two steps sorting for singlethreaded run, we copy the contents of an array to an auxiliary one
            int[] shakerarray;

            if (threaded)
            {
                shakerarray = array;
            }
            else
            {
                shakerarray = new int[array.Length];
                Array.Copy(array, shakerarray, array.Length);
            }

            //a list for storing measured time
            List <long> time = new List <long>();

            //start measuring time from the beginning of sorting
            var watch = new Stopwatch();

            watch.Start();

            time.Add(watch.ElapsedTicks);

            //go through the current array
            for (int i = start; i < end; i++)
            {
                //indicator showing if the elements were swapped
                bool swap = false;

                //go from current element to the end of an array
                for (int j = i; j < end; j++)
                {
                    //if the left element is bigger than the right, swap them
                    if (shakerarray[j + 1] < shakerarray[j])
                    {
                        int temp = shakerarray[j + 1];
                        shakerarray[j + 1] = shakerarray[j];
                        shakerarray[j]     = temp;
                        time.Add(watch.ElapsedTicks);
                        //mark that some elements were swapped
                        swap = true;
                    }
                }

                //return back, so go from the end of an array to current element,
                for (int j = end; j > start; j--)
                {
                    //if the right element is smaller than the left, swap them
                    if (shakerarray[j] < shakerarray[j - 1])
                    {
                        int temp = shakerarray[j - 1];
                        shakerarray[j - 1] = shakerarray[j];
                        shakerarray[j]     = temp;
                        time.Add(watch.ElapsedTicks);
                        //mark that some elements were swapped
                        swap = true;
                    }
                }

                //if no elements were swapped, that means the array is sorted
                if (swap == false)
                {
                    break;
                }
            }

            watch.Stop();

            //in case of multithreaded sorting, we sorted required part of an array and can exit
            if (threaded)
            {
                return;
            }

            //run a second sorting, this time the duration is already measured, so we can create frames during the run

            int frame      = 0;
            int comparison = 0;
            int access     = 0;

            SVGgenerate.GenerateSVG("shakersort", 0, frame, comparison, access, array, time[frame]);

            //go through the current array
            for (int i = 0; i < array.Length / 2; i++)
            {
                //indicator showing if the elements were swapped
                bool swap = false;

                //go from current element to the end of an array
                for (int j = i; j < array.Length - i - 1; j++)
                {
                    comparison++;

                    access = access + 2;

                    //if the left element is bigger than the right, swap them
                    if (array[j + 1] < array[j])
                    {
                        int temp = array[j + 1];
                        array[j + 1] = array[j];
                        array[j]     = temp;

                        frame++;
                        SVGgenerate.GenerateSVG("shakersort", 0, frame, comparison, access, array, time[frame]);
                        //mark that some lements were swapped
                        swap = true;
                    }
                }

                //return back, so go from the end of an array to current element
                for (int j = array.Length - 2 - i; j > i; j--)
                {
                    comparison++;

                    access = access + 2;

                    //if the right element is smaller than the left, swap them
                    if (array[j] < array[j - 1])
                    {
                        int temp = array[j - 1];
                        array[j - 1] = array[j];
                        array[j]     = temp;

                        frame++;
                        SVGgenerate.GenerateSVG("shakersort", 0, frame, comparison, access, array, time[frame]);
                        //mark that some lements were swapped
                        swap = true;
                    }
                }

                //if no elements were swapped, that means the array is sorted
                if (swap == false)
                {
                    break;
                }
            }

            //before we exit, we create an info file summarizing the result of an algorithm
            InfoFile.CreateInfoFile("shakersort", array.Length, time.Last(), comparison, access, 0);
        }
        //method used to run sorting on n separate threads
        //we get a number of threads to sort on, unsorted array, and an object containing an algorithm to sort with
        public static void RunThreads(int threadCount, int[] array, SortingAlgorithm Sorting)
        {
            cnt = 0;

            //get name of sorting algorithm from name of it's class
            string name = Sorting.GetType().Name;

            //generate first frame of unsorted array
            SVGgenerate.GenerateSVG(name, threadCount, cnt++, 0, 0, array, 0);

            //size of an subarray, which will be sorted by one thread
            int part = array.Length / threadCount;

            //an array containing borders of each part
            int[] parts = new int[threadCount];

            //array containing all threads we are sorting with
            Thread[] objThread = new Thread[threadCount];

            //Stopwatch for measuring sorting time
            var watch = new Stopwatch();

            watch.Start();

            //we create a thread for each part and add that thread to an array of threads
            for (int i = 0; i < threadCount - 1; i++)
            {
                //we save the iterator to new integer, else it's value would be non-deterministic in multithreading
                int c = i;

                Thread ThreadSorting = new Thread(() => Sorting.Sort(array, c * part, (c + 1) * part - 1, true));

                objThread[c] = ThreadSorting;

                parts[i] = (c + 1) * part - 1;
            }

            //we create last part, which is supposed to be bigger and contain last elements
            Thread LastThread = new Thread(() => Sorting.Sort(array, (threadCount - 1) * part, array.Length - 1, true));

            objThread[threadCount - 1] = LastThread;
            parts[threadCount - 1]     = array.Length - 1;

            //starting of all threads
            foreach (var thread in objThread)
            {
                thread.Start();
            }

            //waiting for all threads to finish
            foreach (var thread in objThread)
            {
                thread.Join();
            }

            //generate a picture of an array after it is sorted by threads
            //due to the non-deterministic nature of threads, we are not able to generate it sooner
            //however, the user can use sorting without multithreading to see the progress of each algorithm
            SVGgenerate.GenerateSVG(name, threadCount, cnt++, 0, 0, array, watch.ElapsedTicks);

            //Merge all threads together
            MergeThreads(array, threadCount, parts, name, watch);

            watch.Stop();

            //create an info file about this sorting
            InfoFile.CreateInfoFile(name, array.Length, watch.ElapsedTicks, 0, 0, threadCount);
        }
        //Quicksort algorithm implemetation
        //Divide and counter algorithm, it picks a pivot and partitions an array around the pivot.
        //This implementation is iterative, not recursive.
        public void Sort(int[] array, int start, int end, bool threaded)
        {
            int left, right;

            //stack for storing values indicating an array partition
            Stack <int> stack = new Stack <int>();

            stack.Push(start);
            stack.Push(end);

            //in case of two steps sorting for singlethreaded run, we copy the contents of an array to an auxiliary one
            int[] quickarray;

            if (threaded)
            {
                quickarray = array;
            }
            else
            {
                quickarray = new int[array.Length];
                Array.Copy(array, quickarray, array.Length);
            }

            //a list for storing measured time
            List <long> time = new List <long>();

            //start measuring time from the beginning of sorting
            var watch = new Stopwatch();

            watch.Start();

            //iterate until the stack is empty, which means that the array is sorted
            while (stack.Count != 0)
            {
                time.Add(watch.ElapsedTicks);
                //pop two values of stack, bounding the current part of an array
                right = stack.Pop();
                left  = stack.Pop();

                //selects a pivot
                int pivot = FindPivot(quickarray, left, right, time, watch, false);

                //push a correct new boundaries of new partitions into the stack
                if (pivot - 1 > left)
                {
                    stack.Push(left);
                    stack.Push(pivot - 1);
                }

                if (pivot + 1 < right)
                {
                    stack.Push(pivot + 1);
                    stack.Push(right);
                }
            }

            watch.Stop();

            //in case of multithreaded sorting, we sorted required part of an array and can exit
            if (threaded)
            {
                return;
            }

            //run a second sorting, this time the duration is already measured, so we can create frames during the run
            frame      = 0;
            access     = 0;
            comparison = 0;

            stack.Clear();
            stack.Push(0);
            stack.Push(array.Length - 1);

            SVGgenerate.GenerateSVG("quicksort", 0, frame, comparison, access, array, 0);

            while (stack.Count != 0)
            {
                //pop two values of stack, bounding the current part of an array
                right = stack.Pop();
                left  = stack.Pop();

                //selects a pivot
                int pivot = FindPivot(array, left, right, time, watch, true);

                //push a correct new boundaries of new partitions into the stack
                comparison++;
                if (pivot - 1 > left)
                {
                    stack.Push(left);
                    stack.Push(pivot - 1);
                }

                comparison++;
                if (pivot + 1 < right)
                {
                    stack.Push(pivot + 1);
                    stack.Push(right);
                }
            }

            //before we exit, we create an info file summarizing the result of an algorithm
            InfoFile.CreateInfoFile("quicksort", array.Length, time.Last(), comparison, access, 0);
        }
Example #9
0
        //Bubblesort algorithm implementation.
        //It is the simplest algorithm, it works by repeatedly swapping adjanced elements, that are in the wrong order.
        public void Sort(int[] array, int start, int end, bool threaded)
        {
            //in case of two steps sorting for singlethreaded run, we copy the contents of an array to an auxiliary one
            int[] bubblearray;

            if (threaded)
            {
                bubblearray = array;
            }
            else
            {
                bubblearray = new int[array.Length];
                Array.Copy(array, bubblearray, array.Length);
            }

            //a list for storing measured time
            List <long> time = new List <long>();
            //start measuring time from the beginning of sorting
            var watch = new Stopwatch();

            watch.Start();

            time.Add(watch.ElapsedTicks);

            //go through the whole array
            for (int i = start; i <= end; i++)
            {
                //start at beginning and continue to the current element of an array
                for (int j = start; j <= end - 1; j++)
                {
                    //if the left element is bigger than the right, swap them
                    if (bubblearray[j + 1] < bubblearray[j])
                    {
                        //create a temporary integer to store a value in
                        int temp = bubblearray[j + 1];
                        bubblearray[j + 1] = bubblearray[j];
                        bubblearray[j]     = temp;
                        time.Add(watch.ElapsedTicks);
                    }
                }
            }
            watch.Stop();

            //in case of multithreaded sorting, we sorted required part of an array and can exit
            if (threaded)
            {
                return;
            }

            //run a second sorting, this time the duration is already measured, so we can create frames during the run

            int frame       = 0;
            int comparisons = 0;
            int accesses    = 0;

            SVGgenerate.GenerateSVG("bubblesort", 0, frame, comparisons, accesses, array, time[frame]);

            for (int i = 0; i < array.Length - 1; i++)
            {
                //start at beginning and continue to the current element of an array
                for (int j = 0; j < array.Length - i - 1; j++)
                {
                    comparisons++;

                    accesses = accesses + 2;

                    //if the left element is bigger than the right, swap them
                    if (array[j + 1] < array[j])
                    {
                        //create a temporary integer to store a value in
                        int temp = array[j + 1];
                        array[j + 1] = array[j];
                        array[j]     = temp;
                        frame++;
                        SVGgenerate.GenerateSVG("bubblesort", 0, frame, comparisons, accesses, array, time[frame]);
                    }
                }
            }

            //before we exit, we create an info file summarizing the result of an algorithm
            InfoFile.CreateInfoFile("bubblesort", array.Length, time.Last(), comparisons, accesses, 0);
        }
Example #10
0
        //Selectionsort algorithm implementation
        //It sorts an array by repeatedly finding a maximal element and putting it at the end of the array.
        public void Sort(int[] array, int start, int end, bool threaded)
        {
            //in case of two steps sorting for singlethreaded run, we copy the contents of an array to an auxiliary one
            int[] selectionarray;

            if (threaded)
            {
                selectionarray = array;
            }
            else
            {
                selectionarray = new int[array.Length];
                Array.Copy(array, selectionarray, array.Length);
            }

            //a list for storing measured time
            List <long> time = new List <long>();

            //start measuring time from the beginning of sorting
            var watch = new Stopwatch();

            watch.Start();

            time.Add(watch.ElapsedTicks);

            //go through the current array
            for (int i = start; i <= end; i++)
            {
                //mark a maximal value
                int max = i;

                //go through an array from a current element to the end of an array
                for (int j = i + 1; j <= end; j++)
                {
                    //if a current element is bigger than marked maximum
                    if (selectionarray[j] < selectionarray[max])
                    {
                        max = j;
                    }
                }
                //swap the last element with a maximum element
                int temp = selectionarray[i];
                selectionarray[i]   = selectionarray[max];
                selectionarray[max] = temp;
                time.Add(watch.ElapsedTicks);
            }

            watch.Stop();

            //in case of multithreaded sorting, we sorted required part of an array and can exit
            if (threaded)
            {
                return;
            }

            //run a second sorting, this time the duration is already measured, so we can create frames during the run
            int frame      = 0;
            int comparison = 0;
            int access     = 0;

            SVGgenerate.GenerateSVG("selectionsort", 0, frame, comparison, access, array, time[frame]);

            //go through the current array
            for (int i = 0; i < array.Length - 1; i++)
            {
                //mark a maximal value
                int max = i;

                //go through an array from a current element to the end of an array
                for (int j = i + 1; j < array.Length; j++)
                {
                    comparison++;

                    access = access + 2;

                    //if a current element is bigger than marked maximum
                    if (array[j] < array[max])
                    {
                        max = j;
                    }
                }

                access = access + 2;

                //swap the last element with a maximum element
                int temp = array[i];
                array[i]   = array[max];
                array[max] = temp;

                frame++;
                SVGgenerate.GenerateSVG("selectionsort", 0, frame, comparison, access, array, time[frame]);
            }

            //before we exit, we create an info file summarizing the result of an algorithm
            InfoFile.CreateInfoFile("selectionsort", array.Length, time.Last(), comparison, access, 0);
        }
        //Insertionsort algorithm implementation
        //Iterates through the array and when it encounters an element, puts it where it belongs in a sorted array.
        public void Sort(int[] array, int start, int end, bool threaded)
        {
            //in case of two steps sorting for singlethreaded run, we copy the contents of an array to an auxiliary one
            int[] insertarray;

            if (threaded)
            {
                insertarray = array;
            }
            else
            {
                insertarray = new int[array.Length];
                Array.Copy(array, insertarray, array.Length);
            }

            //a list for storing measured time
            List <long> time = new List <long>();

            //start measuring time from the beginning of sorting
            var watch = new Stopwatch();

            watch.Start();

            time.Add(watch.ElapsedTicks);

            //iterate through the current array
            for (int i = start; i < end; i++)
            {
                //get a current element
                int j    = i + 1;
                int temp = insertarray[j];
                //iterate through a sorted array to a place where the current element belongs
                while (j > start && temp < insertarray[j - 1])
                {
                    //swap the elements to preserve a sorted array
                    insertarray[j] = insertarray[j - 1];
                    j--;
                    insertarray[j] = temp;
                    time.Add(watch.ElapsedTicks);
                }
            }

            watch.Stop();

            //in case of multithreaded sorting, we sorted required part of an array and can exit
            if (threaded)
            {
                return;
            }

            //run a second sorting, this time the duration is already measured, so we can create frames during the run

            int frame       = 0;
            int comparisons = 0;
            int accesses    = 0;

            for (int i = 0; i < array.Length - 1; i++)
            {
                //get a current element
                int j    = i + 1;
                int temp = array[j];
                accesses++;
                //iterate through a sorted array to a place where the current element belongs
                while (j > 0 && temp < array[j - 1])
                {
                    comparisons = comparisons + 2;
                    accesses    = accesses + 2;

                    //swap the elements to preserve a sorted array
                    array[j] = array[j - 1];
                    j--;
                    array[j] = temp;

                    frame++;
                    SVGgenerate.GenerateSVG("insertsort", 0, frame, comparisons, accesses, array, time[frame]);
                }
            }
            //before we exit, we create an info file summarizing the result of an algorithm
            InfoFile.CreateInfoFile("insertionsort", array.Length, time.Last(), comparisons, accesses, 0);
        }