Algoritmos de ordenação

Lorival Smolski Chapuis
Lorival Smolski ChapuisSoftware Architect and Senior Full-Stack Developer Web/App at eSauce Marketing & Tecnologia

Relatório sobre o desenvolvimento dos seguintes algoritmos de ordenação:

SOCIEDADE EDUCACIONAL DE SANTA CATARINA

INSTITUTO SUPERIOR TUPY

ENGENHARIA DE COMPUTAÇÃO




                   RELATÓRIO DE DESENVOLVIMENTO

            DE ALGORITMOS DE ORDENAÇÃO EM C#.NET




Aluno: Lorival Smolski Chapuis

Turma: ECP-341

Professor: Glauco Vinicius Scheffel




                              Joinville, 9 de abril de 2011
Sumário
1.     Introdução ............................................................................................................................. 3
2.     Ferramentas e métodos utilizados ........................................................................................ 4
3.     Algoritmos de ordenação ...................................................................................................... 5
     3.1.     BubbleSort ..................................................................................................................... 6
     3.2.     SelectionSort ................................................................................................................. 9
     3.3.     InsertionSort................................................................................................................ 12
     3.4.     MergeSort ................................................................................................................... 15
     3.5.     QuickSort ..................................................................................................................... 21
4.     Execução dos testes automatizados ................................................................................... 24
5.     Estatísticas entre os algoritmos de ordenação ................................................................... 27
6.     Conclusão ............................................................................................................................ 30
1. Introdução


   Este relatório tem como objetivo detalhar o desenvolvimento dos algoritmos de
ordenação bubblesort, selectionsort, insertionsort, mergesort e quicksort.
   Os algoritmos foram desenvolvidos em C# utilizando a IDE Visual Studio 2010, .Net
Framework 4.0, testes automatizados e orientação a aspectos.
   A solução criada possui dois projetos. Um deles é responsável por implementar os
algoritmos de ordenação e o outro responsável apenas pelos testes.
   Ao apresentar cada algoritmo de ordenação, é resumido seu funcionamento e
detalhado o código fonte em C#, que aparece logo em seguida, juntamente com os
códigos dos testes automatizados.
   Ao final foram feitas estatísticas de desempenho comparando os algoritmos,
descritos acima, para ver o tempo de ordenação, de cada um, em um vetor de mil
posições.
   Todos os códigos fontes estão em formas de texto exceto por duas imagens, prints
dos códigos. Isto acontece, pois foi utilizado um recurso chamado “region” que
permite separar e organizar melhor o código, podendo ocultar ou exibir trechos de
códigos. Os prints foram tirados para mostrar o código desejado juntamente com os
regions “fechados”, que serão “abertos” e explicados na sequência.
2. Ferramentas e métodos utilizados
   Para o desenvolvimento dos algoritmos foi utilizado o seguinte ambiente:
            Microsoft Visual Studio 2010;
            Microsoft .Net Framework 4.0 com a linguagem C#;
            Testes automatizados;
            Orientação a aspectos;
   Os testes automatizados foram de dois tipos unitários e integrados. Isto devido à
complexidade de testar alguns métodos e de o autor não querer colocar mocks para
não complicar mais os programas.
   A programação orientada a aspectos – POA – é um paradigma de desenvolvimento
que possibilita implementar funcionalidades que se encontram espalhadas por toda
aplicação (crosscutting concern) de forma encapsulada e modularizada.
   Dentro do .Net Framework um dos princípios do POA é chamado de extension
methods que consiste em desenvolver um algoritmo separado de seu objeto de uso e
armazená-lo junto aos demais métodos do Framework, para ser usado a qualquer
momento de qualquer lugar da solução que utilize a biblioteca em questão.
   Um exemplo de extension method, seria criar um método chamado ToShortString()
para conversão de um datetime (1/12/2999 00:00:00) para uma data curta
(01/12/20999). Ao criar este método informamos que será aplicado ao tipo datetime,
logo os objetos datetime terão mais um método (ToShortString()) podendo ser usado
de qualquer parte da solução e a qualquer momento. Exemplo de uso do método
acima:
   DateTime date = DateTime.Now;
   String shortDate = date.ToShortString();
   Se não utilizar um extension method, o modo convencional seria criar um método
que recebe-se como parâmetro um datetime e retorna-se uma string. Como é apenas
um algoritmo de conversão, poderia estar em uma classe estática chamada
DateConvertionHelper. Veja um exemplo de uso:
   DateTime date = DateTime.Now;
   String shortDate = DateConvertionHelper.ToShortString(date);
   Usar um extension method torna muito mais simples a utilização final.
3. Algoritmos de ordenação
   Para não tornar o relatório longo e ser o mais objetivo possível, cada tópico de
algoritmo será dividido em 3 partes:
      Objetivo;
      Algoritmo;
      Testes.
   Para mais informações sobre os testes, veja o item “4. Execução dos testes
automatizados”.
   Foi criada uma classe chamada SortingAlgorithms que contém os 6 algoritmos de
ordenação. O escopo desta classe está abaixo e o conteúdo dos “regions” estão
detalhados em cada algoritmo.
3.1. BubbleSort


Objetivo: Percorrer o vetor diversas vezes e a cada passagem fazer flutuar para o final
do vetor o item de maior valor. A cada passagem é analisado a quantidade de itens do
vetor menos um, pois o último já estará ordenado.


Algoritmo:
#region BubbleSort
public static void BubbleSort(this IList<int> list)
{
    int lastListPosition = list.Count - 1;
    bool hasChanged = true;


    while (hasChanged)
    {
        hasChanged = false;
        for (int i = 0; i < lastListPosition; i++)
        {
            if (list[i] > list[i + 1])
            {
                var aux = list[i];
                list[i] = list[i + 1];
                list[i + 1] = aux;
                hasChanged = true;
            }
        }
        lastListPosition--;
    }
}
#endregion
Testes:
using System.Linq;
using Lorival.Collections;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Tester
{
  [TestClass]
  public class BubbleSortTestar : AbstractTester
  {
    [TestMethod]
    public void BubbleSortTestar_SortTwoItems()
    {
      //-- Arrange
      int[] expected = { 1, 2 };
      int[] actual = { 2, 1 };

        //-- Act
        actual.BubbleSort();

        //-- Assert
        CollectionAssert.AreEqual(expected, actual);
    }

    [TestMethod]
    public void BubbleSortTestar_SortFiveItemsNeedTwoSteps()
    {
      //-- Arrange
      int[] expected = { 1, 2, 3, 4, 5 };
      int[] actual = { 2, 1, 4, 5, 3 };

        //-- Act
        actual.BubbleSort();

        //-- Assert
        CollectionAssert.AreEqual(expected, actual);
    }

    [TestMethod]
    public void BubbleSortTestar_SortFiveItemsNeedThreeSteps()
    {
      //-- Arrange
      int[] expected = { 10, 12, 35, 43, 101 };
      int[] actual = { 101, 35, 12, 10, 43 };

        //-- Act
        actual.BubbleSort();

        //-- Assert
        CollectionAssert.AreEqual(expected, actual);
    }

    [TestMethod]
    public void BubbleSortTestar_SortTenItems()
    {
      //-- Arrange
int[] expected = { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 };
            int[] actual = { 14, 10, 20, 12, 4, 8, 2, 16, 18, 6 };

            //-- Act
            actual.BubbleSort();

            //-- Assert
            CollectionAssert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void BubbleSortTestar_SortTenItemsWithRepetedValues()
        {
          //-- Arrange
          int[] expected = { 2, 4, 4, 8, 10, 12, 14, 16, 18, 20 };
          int[] actual = { 14, 10, 20, 12, 4, 8, 2, 16, 18, 4 };

            //-- Act
            actual.BubbleSort();

            //-- Assert
            CollectionAssert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void BubbleSortTestar_SortOneHumdredItems()
        {
          //-- Arrange
          NumericListCreator numericListCreator = new NumericListCreator(100);
          int[] actual = numericListCreator.UnorderedList.ToArray<int>();

            //-- Act
            actual.BubbleSort();

            //-- Assert
            CollectionAssert.AreEqual(numericListCreator.OrderedList, actual);
        }
    }
}
3.2. SelectionSort


Objetivo: Percorrer o vetor diversas vezes e a cada passagem trazer para a primeira
posição do vetor o item de menor valor. A cada passagem é analisado a quantidade de
itens do vetor menos um, pois o primeiro já estará ordenado. A grande diferença do
selectionsort para o bubblesort é que o bubble faz varias trocas a cada passagem e a
seleção procura o menor valor e faz apenas uma troca no final da passagem.


Algoritmo:
#region SelectionSort
public static void SelectionSort(this IList<int> list)
{
    int lowestValuePosition = 0;
    for (int lastPosition = 0; lastPosition < list.Count; lastPosition++)
    {
        lowestValuePosition = lastPosition;


        for (int currentPosition = lastPosition; currentPosition < list.Count; currentPosition++)
        {
            if (list[currentPosition] < list[lowestValuePosition])
              lowestValuePosition = currentPosition;
        }


        if (lowestValuePosition > lastPosition)
        {
            var aux = list[lastPosition];
            list[lastPosition] = list[lowestValuePosition];
            list[lowestValuePosition] = aux;
        }
    }
}
#endregion
Testes:
using System.Linq;
using Lorival.Collections;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Tester
{
  [TestClass]
  public class SelectionSortTester : AbstractTester
  {
    [TestMethod]
    public void SelectionSortTester_SortTwoItems()
    {
      //-- Arrange
      int[] expected = { 1, 2 };
      int[] actual = { 2, 1 };

        //-- Act
        actual.SelectionSort();

        //-- Assert
        CollectionAssert.AreEqual(expected, actual);
    }

    [TestMethod]
    public void SelectionSortTester_SortFiveItems()
    {
      //-- Arrange
      int[] expected = { 1, 2, 3, 4, 5 };
      int[] actual = { 2, 1, 4, 5, 3 };

        //-- Act
        actual.SelectionSort();

        //-- Assert
        CollectionAssert.AreEqual(expected, actual);
    }

    [TestMethod]
    public void SelectionSortTester_SortFiveItemsInOtherOrder()
    {
      //-- Arrange
      int[] expected = { 10, 12, 35, 43, 101 };
      int[] actual = { 101, 35, 12, 10, 43 };

        //-- Act
        actual.SelectionSort();

        //-- Assert
        CollectionAssert.AreEqual(expected, actual);
    }

    [TestMethod]
    public void SelectionSortTester_SortTenItems()
    {
      //-- Arrange
int[] expected = { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 };
            int[] actual = { 14, 10, 20, 12, 4, 8, 2, 16, 18, 6 };

            //-- Act
            actual.SelectionSort();

            //-- Assert
            CollectionAssert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void SelectionSortTester_SortTenItemsWithRepetedValues()
        {
          //-- Arrange
          int[] expected = { 2, 4, 4, 8, 10, 12, 14, 16, 18, 20 };
          int[] actual = { 14, 10, 20, 12, 4, 8, 2, 16, 18, 4 };

            //-- Act
            actual.SelectionSort();

            //-- Assert
            CollectionAssert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void SelectionSortTester_SortOneHumdredItems()
        {
          //-- Arrange
          NumericListCreator numericListCreator = new NumericListCreator(100);
          int[] actual = numericListCreator.UnorderedList.ToArray<int>();

            //-- Act
            actual.SelectionSort();

            //-- Assert
            CollectionAssert.AreEqual(numericListCreator.OrderedList, actual);
        }
    }
}
3.3. InsertionSort


Objetivo: Percorrer o vetor da esquerda para a direita e à medida que avança vai
deixando os elementos mais a esquerda ordenados. A cada passagem vai abrindo
espaço para o item corrente e procurando, mais a esquerda qual é o lugar daquele
item. Ao encontrar empurra todos os itens para a direita e insere o item selecionado
no seu respectivo local.


Algoritmo:
#region InsertionSort
public static void InsertionSort(this IList<int> list)
{
    int valueWillBeInserted, lastPosition;


    for (int currentPosition = 1; currentPosition < list.Count; currentPosition++)
    {
        valueWillBeInserted = list[currentPosition];
        lastPosition = currentPosition - 1;
        while (lastPosition >= 0 && list[lastPosition] > valueWillBeInserted)
        {
            list[lastPosition + 1] = list[lastPosition];
            lastPosition--;
        }
        list[lastPosition + 1] = valueWillBeInserted;
    }
}
#endregion
Testes:
using System.Linq;
using Lorival.Collections;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Tester
{
  [TestClass]
  public class InsertionSortTester : AbstractTester
  {
    [TestMethod]
    public void InsertionSortTester_SortTwoItems()
    {
      //-- Arrange
      int[] expected = { 1, 2 };
      int[] actual = { 2, 1 };

        //-- Act
        actual.InsertionSort();

        //-- Assert
        CollectionAssert.AreEqual(expected, actual);
    }

    [TestMethod]
    public void InsertionSortTester_SortFiveItems()
    {
      //-- Arrange
      int[] expected = { 1, 2, 3, 4, 5 };
      int[] actual = { 2, 1, 4, 5, 3 };

        //-- Act
        actual.InsertionSort();

        //-- Assert
        CollectionAssert.AreEqual(expected, actual);
    }

    [TestMethod]
    public void InsertionSortTester_SortFiveItemsInOtherOrder()
    {
      //-- Arrange
      int[] expected = { 10, 12, 35, 43, 101 };
      int[] actual = { 101, 35, 12, 10, 43 };

        //-- Act
        actual.InsertionSort();

        //-- Assert
        CollectionAssert.AreEqual(expected, actual);
    }

    [TestMethod]
    public void InsertionSortTester_SortTenItems()
    {
      //-- Arrange
int[] expected = { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 };
            int[] actual = { 14, 10, 20, 12, 4, 8, 2, 16, 18, 6 };

            //-- Act
            actual.InsertionSort();

            //-- Assert
            CollectionAssert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void InsertionSortTester_SortTenItemsWithRepetedValues()
        {
          //-- Arrange
          int[] expected = { 2, 4, 4, 8, 10, 12, 14, 16, 18, 20 };
          int[] actual = { 14, 10, 20, 12, 4, 8, 2, 16, 18, 4 };

            //-- Act
            actual.InsertionSort();

            //-- Assert
            CollectionAssert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void InsertionSortTester_SortOneHumdredItems()
        {
          //-- Arrange
          NumericListCreator numericListCreator = new NumericListCreator(100);
          int[] actual = numericListCreator.UnorderedList.ToArray<int>();

            //-- Act
            actual.InsertionSort();

            //-- Assert
            CollectionAssert.AreEqual(numericListCreator.OrderedList, actual);
        }
    }
}
3.4. MergeSort
Objetivo: Criar uma sequência ordenada baseada em outras duas também ordenadas.
Para isto é necessário dividir a sequência original até chegar a um limite ordenável por
um insertionSort (100 itens neste exemplo) ou até sobrarem pares para ordenar.
Depois vai agrupando todas as sequências divididas até formar a sequência ordenada.


Modo com InsertionSort e sem InsertionSort




       Foi desenvolvido dois métodos de chamada. Um para mergeSort com
InsertionSort e outro sem InsertionSort. Ambos utilizam o mesmo algoritmo para
ordenação com a diferença de um parâmetro que informa se irá usar o algoritmo
InsertionSort quando chegar nos 100 itens ou não.
Algoritmo:
#region Private Methods
private static IList<int> ExecuteMergeSort(IList<int> list, bool sortWithInsertionSort)
{
  if (sortWithInsertionSort)
  {
      if (list.Count <= 100)
      {
         list.InsertionSort();
         return list;
      }
  }
  else
      if (list.Count <= 1)
         return list;

  int midlePosition = list.Count / 2;

  IList<int> leftSide = new List<int>();
  IList<int> rightSide = new List<int>();

  for (int i = 0; i < midlePosition; i++)
    leftSide.Add(list[i]);

  for (int i = midlePosition; i < list.Count; i++)
    rightSide.Add(list[i]);

  return ExecuteMergeSort(ExecuteMergeSort(leftSide, sortWithInsertionSort),
ExecuteMergeSort(rightSide, sortWithInsertionSort));
}

private static IList<int> ExecuteMergeSort(IList<int> left, IList<int> right)
{
  IList<int> listToBeReturned = new List<int>();

  while (left.Count > 0 && right.Count > 0)
   if (left[0] > right[0])
   {
      listToBeReturned.Add(right[0]);
      right.RemoveAt(0);
   }
   else
   {
      listToBeReturned.Add(left[0]);
      left.RemoveAt(0);
   }

  for (int i = 0; i < left.Count; i++)
    listToBeReturned.Add(left[i]);

  for (int i = 0; i < right.Count; i++)
    listToBeReturned.Add(right[i]);

  return listToBeReturned;
}
#endregion
Testes:
using System.Linq;
using Lorival.Collections;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Tester
{
  [TestClass]
  public class MergeTester : AbstractTester
  {
    #region WithOutInsertionSort
    [TestMethod]
    public void MergeTester_SortTwoItems()
    {
      //-- Arrange
      int[] expected = { 1, 2 };
      int[] actual = { 2, 1 };

        //-- Act
        actual.MergeSort();

        //-- Assert
        CollectionAssert.AreEqual(expected, actual);
    }

    [TestMethod]
    public void MergeTester_SortFiveItems()
    {
      //-- Arrange
      int[] expected = { 1, 2, 3, 4, 5 };
      int[] actual = { 2, 1, 4, 5, 3 };

        //-- Act
        actual.MergeSort();

        //-- Assert
        CollectionAssert.AreEqual(expected, actual);
    }

    [TestMethod]
    public void MergeTester_SortFiveItemsInOtherOrder()
    {
      //-- Arrange
      int[] expected = { 10, 12, 35, 43, 101 };
      int[] actual = { 101, 35, 12, 10, 43 };

        //-- Act
        actual.MergeSort();

        //-- Assert
        CollectionAssert.AreEqual(expected, actual);
    }

    [TestMethod]
    public void MergeTester_SortTenItems()
    {
//-- Arrange
    int[] expected = { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 };
    int[] actual = { 14, 10, 20, 12, 4, 8, 2, 16, 18, 6 };

    //-- Act
    actual.MergeSort();

    //-- Assert
    CollectionAssert.AreEqual(expected, actual);
}

[TestMethod]
public void MergeTester_SortTenItemsWithRepetedValues()
{
  //-- Arrange
  int[] expected = { 2, 4, 4, 8, 10, 12, 14, 16, 18, 20 };
  int[] actual = { 14, 10, 20, 12, 4, 8, 2, 16, 18, 4 };

    //-- Act
    actual.MergeSort();

    //-- Assert
    CollectionAssert.AreEqual(expected, actual);
}

[TestMethod]
public void MergeTester_SortOneHumdredItems()
{
  //-- Arrange
  NumericListCreator numericListCreator = new NumericListCreator(100);
  int[] actual = numericListCreator.UnorderedList.ToArray<int>();

    //-- Act
    actual.MergeSort();

    //-- Assert
    CollectionAssert.AreEqual(numericListCreator.OrderedList, actual);
}
#endregion

#region WithInsertionSort
[TestMethod]
public void MergeTester_SortTwoItems_WithInsertionSort()
{
  //-- Arrange
  int[] expected = { 1, 2 };
  int[] actual = { 2, 1 };

    //-- Act
    actual.MergeSortWithInsertionSort();

    //-- Assert
    CollectionAssert.AreEqual(expected, actual);
}

[TestMethod]
public void MergeTester_SortFiveItems_WithInsertionSort()
{
    //-- Arrange
    int[] expected = { 1, 2, 3, 4, 5 };
    int[] actual = { 2, 1, 4, 5, 3 };

    //-- Act
    actual.MergeSortWithInsertionSort();

    //-- Assert
    CollectionAssert.AreEqual(expected, actual);
}

[TestMethod]
public void MergeTester_SortFiveItemsInOtherOrder_WithInsertionSort()
{
  //-- Arrange
  int[] expected = { 10, 12, 35, 43, 101 };
  int[] actual = { 101, 35, 12, 10, 43 };

    //-- Act
    actual.MergeSortWithInsertionSort();

    //-- Assert
    CollectionAssert.AreEqual(expected, actual);
}

[TestMethod]
public void MergeTester_SortTenItems_WithInsertionSort()
{
  //-- Arrange
  int[] expected = { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 };
  int[] actual = { 14, 10, 20, 12, 4, 8, 2, 16, 18, 6 };

    //-- Act
    actual.MergeSortWithInsertionSort();

    //-- Assert
    CollectionAssert.AreEqual(expected, actual);
}

[TestMethod]
public void MergeTester_SortTenItemsWithRepetedValues_WithInsertionSort()
{
  //-- Arrange
  int[] expected = { 2, 4, 4, 8, 10, 12, 14, 16, 18, 20 };
  int[] actual = { 14, 10, 20, 12, 4, 8, 2, 16, 18, 4 };

    //-- Act
    actual.MergeSortWithInsertionSort();

    //-- Assert
    CollectionAssert.AreEqual(expected, actual);
}

[TestMethod]
public void MergeTester_SortOneHumdredItems_WithInsertionSort()
{
//-- Arrange
         NumericListCreator numericListCreator = new NumericListCreator(100);
         int[] actual = numericListCreator.UnorderedList.ToArray<int>();

         //-- Act
         actual.MergeSortWithInsertionSort();

         //-- Assert
         CollectionAssert.AreEqual(numericListCreator.OrderedList, actual);
        }
        #endregion
    }
}
3.5. QuickSort
Objetivo: Ordena o vetor dividindo-o recursivamente, através de um pivô, colocando
os itens menores que o pivô de um lado e maiores do outro. Ao final os itens estarão
ordenados. Este é o algoritmo mais rápido e eficiente para ordenação para vetores
grandes.


Algoritmo:
#region QuickSort
public static void QuickSort(this IList<int> list)
{
  Sort(list, 0, list.Count - 1);
}

#region Private Methods
private static void Sort(IList<int> list, int startPosition, int endPosition)
{
  if (startPosition < endPosition)
  {
      int pivotPosition = Partition(list, startPosition, endPosition);
      Sort(list, startPosition, pivotPosition - 1);
      Sort(list, pivotPosition + 1, endPosition);
  }
}

private static int Partition(IList<int> list, int startPosition, int endPosition)
{
  int pivo = list[startPosition];
  int startPartitionPosition = startPosition + 1, endPartitionPosition = endPosition;
  while (startPartitionPosition <= endPartitionPosition)
  {
     if (list[startPartitionPosition] <= pivo)
        startPartitionPosition++;
     else if (pivo < list[endPartitionPosition])
        endPartitionPosition--;
     else
     {
        int troca = list[startPartitionPosition];
        list[startPartitionPosition] = list[endPartitionPosition];
        list[endPartitionPosition] = troca;
        startPartitionPosition++;
        endPartitionPosition--;
     }
  }
  list[startPosition] = list[endPartitionPosition];
  list[endPartitionPosition] = pivo;
  return endPartitionPosition;
}
#endregion
#endregion
Testes:
using System.Linq;
using Lorival.Collections;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Tester
{
  [TestClass]
  public class QuickSortTester : AbstractTester
  {
    [TestMethod]
    public void QuickSortTester_SortTwoItems()
    {
      //-- Arrange
      int[] expected = { 1, 2 };
      int[] actual = { 2, 1 };

        //-- Act
        actual.QuickSort();

        //-- Assert
        CollectionAssert.AreEqual(expected, actual);
    }

    [TestMethod]
    public void QuickSortTester_SortFiveItems()
    {
      //-- Arrange
      int[] expected = { 1, 2, 3, 4, 5 };
      int[] actual = { 2, 1, 4, 5, 3 };

        //-- Act
        actual.QuickSort();

        //-- Assert
        CollectionAssert.AreEqual(expected, actual);
    }

    [TestMethod]
    public void QuickSortTester_SortFiveItemsInOtherOrder()
    {
      //-- Arrange
      int[] expected = { 10, 12, 35, 43, 101 };
      int[] actual = { 101, 35, 12, 10, 43 };

        //-- Act
        actual.QuickSort();

        //-- Assert
        CollectionAssert.AreEqual(expected, actual);
    }

    [TestMethod]
    public void QuickSortTester_SortTenItems()
    {
      //-- Arrange
int[] expected = { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 };
            int[] actual = { 14, 10, 20, 12, 4, 8, 2, 16, 18, 6 };

            //-- Act
            actual.QuickSort();

            //-- Assert
            CollectionAssert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void QuickSortTester_SortTenItemsWithRepetedValues()
        {
          //-- Arrange
          int[] expected = { 2, 4, 4, 8, 10, 12, 14, 16, 18, 20 };
          int[] actual = { 14, 10, 20, 12, 4, 8, 2, 16, 18, 4 };

            //-- Act
            actual.QuickSort();

            //-- Assert
            CollectionAssert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void QuickSortTester_SortOneHumdredItems()
        {
          //-- Arrange
          NumericListCreator numericListCreator = new NumericListCreator(100);
          int[] actual = numericListCreator.UnorderedList.ToArray<int>();

            //-- Act
            actual.QuickSort();

            //-- Assert
            CollectionAssert.AreEqual(numericListCreator.OrderedList, actual);
        }
    }
}
4. Execução dos testes automatizados


    Para facilitar os testes automatizados para grandes vetores foi criado uma classe chamada
NumericListCreator que tem como objetivo criar dois vetores iguais com a diferença que um
está ordenado e o outro não. Quando criamos a instância desta classe informamos o tamanho
do vetor que queremos e ela disponibiliza duas propriedades, cada uma sendo um vetor.

        Para criar os dois vetores com os mesmos valores, foi utilizado um recurso do .Net
Framework. Na verdade é um objeto chamado SortedList, que nada mais é do que uma lista
que se ordena conforme vai incluindo os itens. Esta classe gera os vetores com no máximo cem
mil posições.

              Veja abaixo a codificação desta classe:

using System.Collections;
using System.Collections.Generic;
using Lorival.Collections;
using System;

namespace Tester
{
  internal class NumericListCreator
  {
    internal IList OrderedList { get; private set; }
    internal IList<int> UnorderedList { get; private set; }
    private const int limitGeneratedLists = 100000;

        internal NumericListCreator(int listSize)
        {
          OrderedList = new List<int>();
          UnorderedList = new List<int>();

            if (listSize > limitGeneratedLists)
               listSize = limitGeneratedLists;

            SortedList sortedList = new SortedList();
            while(sortedList.Count < listSize)
            {
              int randowNumber = new Random().Next(limitGeneratedLists);
              if (!sortedList.ContainsKey(randowNumber))
              {
                  sortedList.Add(randowNumber, null);
                  UnorderedList.Add(randowNumber);
              }
            }

            OrderedList = sortedList.GetKeyList();
        }
    }
}
Todos os testes foram escritos seguindo um pouco de babysteps. Começam com
vetores de duas posições e vai aumentando até um vetor de 100 posições, gerado através do
objeto gerador de vetores já citado.

       Foi criada uma classe abstrata para os testes. Esta tem como único objetivo armazenar
informações pertinentes ao framework de testes. Veja abaixo:

using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Tester
{
  public abstract class AbstractTester
  {
    /// <summary>
    ///Gets or sets the test context which provides
    ///information about and functionality for the current test run.
    ///</summary>
    public TestContext TestContext { get;set;}


        #region Additional test attributes
        //
        // You can use the following additional attributes as you write your tests:
        //
        // Use ClassInitialize to run code before running the first test in the class
        // [ClassInitialize()]
        // public static void MyClassInitialize(TestContext testContext) { }
        //
        // Use ClassCleanup to run code after all tests in a class have run
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }
        //
        // Use TestInitialize to run code before running each test
        // [TestInitialize()]
        // public void MyTestInitialize() { }
        //
        // Use TestCleanup to run code after each test has run
        // [TestCleanup()]
        // public void MyTestCleanup() { }
        //
        #endregion
    }
}
Abaixo segue o resultado da execução de todos os 36 testes.
5. Estatísticas entre os algoritmos de ordenação


    Abaixo segue tabelas comparando o tempo de execução dos algoritmos ordenando
vetores. Para a realização dos testes foi gerado um vetor com valores aleatórios e utilizado o
mesmo vetor para todos os algoritmos. O programa utilizado será explicado após as tabelas de
comparação.



Ordenando vetores com 10 itens
BubbleSort                                     {00:00:00}
SelectionSort                                  {00:00:00.0010001}
InsertionSort                                  {00:00:00}
MergeSort                                      {00:00:00.0020002}
MergeSortWithInsertionSort                     {00:00:00}
QuickSort                                      {00:00:00.0010001}


Ordenando vetores com 100 itens
BubbleSort                                     {00:00:00.0012501}
SelectionSort                                  {00:00:00.0010001}
InsertionSort                                  {00:00:00.0012501}
MergeSort                                      {00:00:00.0012501}
MergeSortWithInsertionSort                     {00:00:00.0012501}
QuickSort                                      {00:00:00.0012500}



Ordenando vetores com 1000 itens
BubbleSort                                     {00:00:00.0179982}
SelectionSort                                  {00:00:00.0109989}
InsertionSort                                  {00:00:00.0069993}
MergeSort                                      {00:00:00.0029997}
MergeSortWithInsertionSort                     {00:00:00.0019998}
QuickSort                                      {00:00:00.0019998}



Ordenando vetores com 10000 itens
BubbleSort                                     {00:00:01.6988304}
SelectionSort                                  {00:00:01.0148985}
InsertionSort                                  {00:00:00.6489351}
MergeSort                                      {00:00:00.0749925}
MergeSortWithInsertionSort                     {00:00:00.0569943}
QuickSort                                      {00:00:00.0059994}
Ordenando vetores com 50000 itens
BubbleSort                                            {00:00:41.9553894}
SelectionSort                                         {00:00:28.3195700}
InsertionSort                                         {00:00:16.4596458}
MergeSort                                             {00:00:01.2951295}
MergeSortWithInsertionSort                            {00:00:01.1681168}
QuickSort                                             {00:00:00.0280028}


    Para implementar os extensions methods (orientação a aspectos) é necessário utilizar
classes estáticas. Estas por sua vez não permite herdar de interfaces o que inviabiliza a
aplicação do command pattern.
    Pela ótica de como foi desenvolvido, o projeto responsável por contemplar o programa
que gera as estatísticas foi o projeto de testes, visto que as estatísticas, neste caso, fazem
parte dos testes de avaliação do software.
    Abaixo segue a classe que gerou as estatísticas apresentadas:

using System;
using System.Linq;
using Lorival.Collections;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Tester
{
  [TestClass]
  public class SpeedTester : AbstractTester
  {
    [TestMethod]
    public void EffectTest()
    {
      DateTime startTime;
      DateTime endTime;

      startTime = DateTime.Now;
      NumericListCreator numericListCreator = new NumericListCreator(50000);
      endTime = DateTime.Now;
      TimeSpan numericListCreatorSpeedTime = endTime - startTime;

      startTime = DateTime.Now;
      int[] bubble = numericListCreator.UnorderedList.ToArray<int>();
      bubble.BubbleSort();
      endTime = DateTime.Now;
      TimeSpan bubbleSpeedTime = endTime - startTime;
      //--
      startTime = DateTime.Now;
      int[] selection = numericListCreator.UnorderedList.ToArray<int>();
      selection.SelectionSort();
      endTime = DateTime.Now;
      TimeSpan selectionSpeedTime = endTime - startTime;
      //--
      startTime = DateTime.Now;
int[] insertion = numericListCreator.UnorderedList.ToArray<int>();
            insertion.InsertionSort();
            endTime = DateTime.Now;
            TimeSpan insertionSpeedTime = endTime - startTime;
            //--
            startTime = DateTime.Now;
            int[] merge = numericListCreator.UnorderedList.ToArray<int>();
            merge.MergeSort();
            endTime = DateTime.Now;
            TimeSpan mergeSpeedTime = endTime - startTime;
            //--
            startTime = DateTime.Now;
            int[] mergeWithInsertion = numericListCreator.UnorderedList.ToArray<int>();
            mergeWithInsertion.MergeSortWithInsertionSort();
            endTime = DateTime.Now;
            TimeSpan mergeWithInsertionSpeedTime = endTime - startTime;
            //--
            startTime = DateTime.Now;
            int[] quick = numericListCreator.UnorderedList.ToArray<int>();
            quick.QuickSort();
            endTime = DateTime.Now;
            TimeSpan quickSpeedTime = endTime - startTime;
        }
    }
}
6. Conclusão


       Os objetivos do trabalho foram alcançados com sucesso, ou seja, foi possível construir
todos os algoritmos e apresenta-los neste relatório juntamente com estatísticas de
desempenho de cada um.
       O tempo aproximado total utilizado para desenvolvimento e geração deste relatório
foi de doze horas.
       Os testes unitários foram imprescindíveis para a perfeita conclusão de todos os
algoritmos. Mesmo depois de concluído cada um, foi necessário passar por uma fase de
revisão e refinação o que permitiu serem feitas de forma muito mais rápidas e assertivas, visto
que existiam testes validando a ordenação de todos os algoritmos.
       O maior problema encontrado foi na geração de um vetor não ordenado com valores
aleatórios para a realização dos testes. Como esta era uma responsabilidade do projeto de
testes foi possível utilizar o “SortedList” para facilitar o desenvolvimento, porém o tempo para
geração de um vetor de 50 mil posições sem valores repetidos foi de quase 20 minutos.
Existem várias outras formas de gerar este vetor, porém como não fazia parte dos objetivos
propostos e fazia parte apenas dos testes foi utilizada a forma mais rápida de desenvolver, que
implicou unicamente em ter maior tempo de espera na geração das estatísticas.
       Por fim o trabalho foi de grande valia para entendimento, principalmente, das
diferenças de desempenho entre os algoritmos de ordenação e compreender que sempre
existem métodos mais eficientes de resolver um problema recorrente.

Recommended

Trabalho métodos de ordenação by
Trabalho métodos de ordenaçãoTrabalho métodos de ordenação
Trabalho métodos de ordenaçãoDaiana de Ávila
18K views17 slides
Ordenação by
OrdenaçãoOrdenação
OrdenaçãoSérgio Souza Costa
4.2K views60 slides
Lista Duplamente Encadeada by
Lista Duplamente EncadeadaLista Duplamente Encadeada
Lista Duplamente EncadeadaMatheus Santos Almeida
9.1K views12 slides
Bubble Sort by
Bubble SortBubble Sort
Bubble SortDaniel Arndt Alves
8.4K views104 slides
Algoritmo Shell Sort by
Algoritmo Shell SortAlgoritmo Shell Sort
Algoritmo Shell SortGabriel Albuquerque
7.3K views17 slides
Sistemas de Arquivos FAT x NTFS by
Sistemas de Arquivos FAT x NTFSSistemas de Arquivos FAT x NTFS
Sistemas de Arquivos FAT x NTFSCleber Ramos
27.6K views67 slides

More Related Content

What's hot

Atalhos no windows 7 by
Atalhos no windows 7Atalhos no windows 7
Atalhos no windows 7Davi Felipe Russi
1K views15 slides
Instalação e Manutenção: Introdução a Arquitetura de Computadores by
Instalação e Manutenção: Introdução a Arquitetura de ComputadoresInstalação e Manutenção: Introdução a Arquitetura de Computadores
Instalação e Manutenção: Introdução a Arquitetura de ComputadoresNatanael Simões
2.2K views22 slides
Treinamento processos draw io by
Treinamento processos draw ioTreinamento processos draw io
Treinamento processos draw ioRafael Lisboa
8.2K views22 slides
Estrutura de Dados - Listas Encadeadas by
Estrutura de Dados - Listas EncadeadasEstrutura de Dados - Listas Encadeadas
Estrutura de Dados - Listas EncadeadasAdriano Teixeira de Souza
21.5K views27 slides
Algoritmos gulosos by
Algoritmos gulososAlgoritmos gulosos
Algoritmos gulososMarcos Castro
2.9K views7 slides
Estrutura de Dados - Aula 15 - Pesquisa de Dados (Árvore de Pesquisa) by
Estrutura de Dados - Aula 15 - Pesquisa de Dados (Árvore de Pesquisa)Estrutura de Dados - Aula 15 - Pesquisa de Dados (Árvore de Pesquisa)
Estrutura de Dados - Aula 15 - Pesquisa de Dados (Árvore de Pesquisa)Leinylson Fontinele
1.1K views121 slides

What's hot(20)

Instalação e Manutenção: Introdução a Arquitetura de Computadores by Natanael Simões
Instalação e Manutenção: Introdução a Arquitetura de ComputadoresInstalação e Manutenção: Introdução a Arquitetura de Computadores
Instalação e Manutenção: Introdução a Arquitetura de Computadores
Natanael Simões2.2K views
Treinamento processos draw io by Rafael Lisboa
Treinamento processos draw ioTreinamento processos draw io
Treinamento processos draw io
Rafael Lisboa8.2K views
Estrutura de Dados - Aula 15 - Pesquisa de Dados (Árvore de Pesquisa) by Leinylson Fontinele
Estrutura de Dados - Aula 15 - Pesquisa de Dados (Árvore de Pesquisa)Estrutura de Dados - Aula 15 - Pesquisa de Dados (Árvore de Pesquisa)
Estrutura de Dados - Aula 15 - Pesquisa de Dados (Árvore de Pesquisa)
Leinylson Fontinele1.1K views
Estrutura de Dados e Algoritmos com Java #02-12: Vetores e Arrays by Loiane Groner
Estrutura de Dados e Algoritmos com Java #02-12: Vetores e ArraysEstrutura de Dados e Algoritmos com Java #02-12: Vetores e Arrays
Estrutura de Dados e Algoritmos com Java #02-12: Vetores e Arrays
Loiane Groner20.9K views
Análise de desempenho de algoritmos de ordenação by Gustavo Carvalho
Análise de desempenho de algoritmos de ordenaçãoAnálise de desempenho de algoritmos de ordenação
Análise de desempenho de algoritmos de ordenação
Gustavo Carvalho8.7K views
15 algoritmos de busca em tabelas - sequencial e binaria by Ricardo Bolanho
15   algoritmos de busca em tabelas - sequencial e binaria15   algoritmos de busca em tabelas - sequencial e binaria
15 algoritmos de busca em tabelas - sequencial e binaria
Ricardo Bolanho4K views
Curso HTML 5 - Aula com Formulários, Imagens, Áudio e Vídeo by Tiago Antônio da Silva
Curso HTML 5 - Aula com Formulários, Imagens, Áudio e VídeoCurso HTML 5 - Aula com Formulários, Imagens, Áudio e Vídeo
Curso HTML 5 - Aula com Formulários, Imagens, Áudio e Vídeo
Discos e sistemas de arquivos em Linux by Fábio dos Reis
Discos e sistemas de arquivos em LinuxDiscos e sistemas de arquivos em Linux
Discos e sistemas de arquivos em Linux
Fábio dos Reis14.1K views
Complexidade de algoritmos insertion, selection e bubble sort. by Júlio Rocha
Complexidade de algoritmos insertion, selection e bubble sort.Complexidade de algoritmos insertion, selection e bubble sort.
Complexidade de algoritmos insertion, selection e bubble sort.
Júlio Rocha24K views
Metodos de ordenação estrutura de dados by Thalita Chaves
Metodos de ordenação   estrutura de dadosMetodos de ordenação   estrutura de dados
Metodos de ordenação estrutura de dados
Thalita Chaves10.2K views
Lista de Exerícios - Manutenção e Redes de Computadores IFNMG - Campus Januária by Suzana Viana Mota
Lista de Exerícios - Manutenção e Redes de Computadores IFNMG - Campus JanuáriaLista de Exerícios - Manutenção e Redes de Computadores IFNMG - Campus Januária
Lista de Exerícios - Manutenção e Redes de Computadores IFNMG - Campus Januária
Suzana Viana Mota1.1K views

Viewers also liked

Análise de Algoritmos de Ordenação Interna by
Análise de Algoritmos de Ordenação InternaAnálise de Algoritmos de Ordenação Interna
Análise de Algoritmos de Ordenação InternaJohnnatan Messias
1.2K views55 slides
Comparação Experimental de Algoritmos de Ordenação by
Comparação Experimental de Algoritmos de OrdenaçãoComparação Experimental de Algoritmos de Ordenação
Comparação Experimental de Algoritmos de OrdenaçãoLenon Fachiano
3.1K views21 slides
Ordenação de Dados por Distribuição de Chaves by
Ordenação de Dados por Distribuição de ChavesOrdenação de Dados por Distribuição de Chaves
Ordenação de Dados por Distribuição de ChavesMauricio Volkweis Astiazara
2.4K views13 slides
Análise empírica de algoritmos de ordenação by
Análise empírica de algoritmos de ordenaçãoAnálise empírica de algoritmos de ordenação
Análise empírica de algoritmos de ordenaçãoOrlando Junior
13.5K views19 slides
Complexidade de Algoritmos, Notação assintótica, Algoritmos polinomiais e in... by
Complexidade de Algoritmos, Notação assintótica, Algoritmos polinomiais e in...Complexidade de Algoritmos, Notação assintótica, Algoritmos polinomiais e in...
Complexidade de Algoritmos, Notação assintótica, Algoritmos polinomiais e in...Universidade de São Paulo
9.9K views50 slides
métodos ordenação C, bolha, selection sort e insertion sort by
métodos ordenação C, bolha, selection sort e insertion sortmétodos ordenação C, bolha, selection sort e insertion sort
métodos ordenação C, bolha, selection sort e insertion sortAlessandro Trevisan
20.2K views35 slides

Viewers also liked(7)

Análise de Algoritmos de Ordenação Interna by Johnnatan Messias
Análise de Algoritmos de Ordenação InternaAnálise de Algoritmos de Ordenação Interna
Análise de Algoritmos de Ordenação Interna
Johnnatan Messias1.2K views
Comparação Experimental de Algoritmos de Ordenação by Lenon Fachiano
Comparação Experimental de Algoritmos de OrdenaçãoComparação Experimental de Algoritmos de Ordenação
Comparação Experimental de Algoritmos de Ordenação
Lenon Fachiano3.1K views
Análise empírica de algoritmos de ordenação by Orlando Junior
Análise empírica de algoritmos de ordenaçãoAnálise empírica de algoritmos de ordenação
Análise empírica de algoritmos de ordenação
Orlando Junior13.5K views
Complexidade de Algoritmos, Notação assintótica, Algoritmos polinomiais e in... by Universidade de São Paulo
Complexidade de Algoritmos, Notação assintótica, Algoritmos polinomiais e in...Complexidade de Algoritmos, Notação assintótica, Algoritmos polinomiais e in...
Complexidade de Algoritmos, Notação assintótica, Algoritmos polinomiais e in...
métodos ordenação C, bolha, selection sort e insertion sort by Alessandro Trevisan
métodos ordenação C, bolha, selection sort e insertion sortmétodos ordenação C, bolha, selection sort e insertion sort
métodos ordenação C, bolha, selection sort e insertion sort
Alessandro Trevisan20.2K views
Faça Apresentações! Não Faça Slides! by Victor Gonçalves
Faça Apresentações! Não Faça Slides!Faça Apresentações! Não Faça Slides!
Faça Apresentações! Não Faça Slides!
Victor Gonçalves20.7K views

Similar to Algoritmos de ordenação

As Novidades Do C# 4.0 - NetPonto by
As Novidades Do C# 4.0 - NetPontoAs Novidades Do C# 4.0 - NetPonto
As Novidades Do C# 4.0 - NetPontoPaulo Morgado
1.4K views48 slides
ESTRUTURA DE DADOS (JAVA) AULA 09 by
ESTRUTURA DE DADOS (JAVA) AULA 09ESTRUTURA DE DADOS (JAVA) AULA 09
ESTRUTURA DE DADOS (JAVA) AULA 09ETEC Monsenhor Antonio Magliano
2.1K views13 slides
Mock Objects by
Mock ObjectsMock Objects
Mock Objectselliando dias
684 views17 slides
Threads 09: Paralelismo by
Threads 09: ParalelismoThreads 09: Paralelismo
Threads 09: ParalelismoHelder da Rocha
455 views35 slides
Testes em Aplicações Web com Cactus by
Testes em Aplicações Web com CactusTestes em Aplicações Web com Cactus
Testes em Aplicações Web com CactusDenis L Presciliano
462 views19 slides
ASP.Net Módulo 2 by
ASP.Net   Módulo 2ASP.Net   Módulo 2
ASP.Net Módulo 2michellobo
450 views38 slides

Similar to Algoritmos de ordenação(20)

As Novidades Do C# 4.0 - NetPonto by Paulo Morgado
As Novidades Do C# 4.0 - NetPontoAs Novidades Do C# 4.0 - NetPonto
As Novidades Do C# 4.0 - NetPonto
Paulo Morgado1.4K views
ASP.Net Módulo 2 by michellobo
ASP.Net   Módulo 2ASP.Net   Módulo 2
ASP.Net Módulo 2
michellobo450 views
Maratona de Programação com STL by Marcos Castro
Maratona de Programação com STLMaratona de Programação com STL
Maratona de Programação com STL
Marcos Castro2.5K views
Refatoração de código com Capitão Nascimento versão completa by Eduardo Bregaida
Refatoração de código com Capitão Nascimento versão completaRefatoração de código com Capitão Nascimento versão completa
Refatoração de código com Capitão Nascimento versão completa
Eduardo Bregaida1.6K views
Utilitários para Programação Concorrente em Java (2005) by Helder da Rocha
Utilitários para Programação Concorrente em Java (2005)Utilitários para Programação Concorrente em Java (2005)
Utilitários para Programação Concorrente em Java (2005)
Helder da Rocha1.2K views
Curso java 01 - molhando os pés com java by Maurício Linhares
Curso java   01 - molhando os pés com javaCurso java   01 - molhando os pés com java
Curso java 01 - molhando os pés com java
Maurício Linhares1.5K views
Aula5 by fkimura
Aula5Aula5
Aula5
fkimura596 views
Threads 08: Executores e Futures by Helder da Rocha
Threads 08: Executores e FuturesThreads 08: Executores e Futures
Threads 08: Executores e Futures
Helder da Rocha565 views
Lista IV de Programação Orientada a Objetos by unifesptk
Lista IV de Programação Orientada a ObjetosLista IV de Programação Orientada a Objetos
Lista IV de Programação Orientada a Objetos
unifesptk358 views
TDC2016POA | Trilha Android - Testes no Android by tdc-globalcode
TDC2016POA | Trilha Android - Testes no AndroidTDC2016POA | Trilha Android - Testes no Android
TDC2016POA | Trilha Android - Testes no Android
tdc-globalcode294 views

More from Lorival Smolski Chapuis

Uso de uma rede neural artificial para previsão do volume de lodo gerado em e... by
Uso de uma rede neural artificial para previsão do volume de lodo gerado em e...Uso de uma rede neural artificial para previsão do volume de lodo gerado em e...
Uso de uma rede neural artificial para previsão do volume de lodo gerado em e...Lorival Smolski Chapuis
591 views9 slides
Joinville Dojo 2010 by
Joinville Dojo   2010Joinville Dojo   2010
Joinville Dojo 2010Lorival Smolski Chapuis
531 views44 slides
Domain driven design - Visão Geral by
Domain driven design - Visão GeralDomain driven design - Visão Geral
Domain driven design - Visão GeralLorival Smolski Chapuis
1.1K views57 slides
DotNet Framework e Orientação a Objetos 1 - Introdução by
DotNet Framework e Orientação a Objetos 1 - IntroduçãoDotNet Framework e Orientação a Objetos 1 - Introdução
DotNet Framework e Orientação a Objetos 1 - IntroduçãoLorival Smolski Chapuis
14.4K views223 slides
Aula inaugural da GeraçãoTec - Softville/Joinville by
Aula inaugural da GeraçãoTec - Softville/JoinvilleAula inaugural da GeraçãoTec - Softville/Joinville
Aula inaugural da GeraçãoTec - Softville/JoinvilleLorival Smolski Chapuis
694 views60 slides
Tutorial realidade aumentada - Sociesc 2011 by
Tutorial realidade aumentada - Sociesc 2011Tutorial realidade aumentada - Sociesc 2011
Tutorial realidade aumentada - Sociesc 2011Lorival Smolski Chapuis
1.3K views14 slides

Algoritmos de ordenação

  • 1. SOCIEDADE EDUCACIONAL DE SANTA CATARINA INSTITUTO SUPERIOR TUPY ENGENHARIA DE COMPUTAÇÃO RELATÓRIO DE DESENVOLVIMENTO DE ALGORITMOS DE ORDENAÇÃO EM C#.NET Aluno: Lorival Smolski Chapuis Turma: ECP-341 Professor: Glauco Vinicius Scheffel Joinville, 9 de abril de 2011
  • 2. Sumário 1. Introdução ............................................................................................................................. 3 2. Ferramentas e métodos utilizados ........................................................................................ 4 3. Algoritmos de ordenação ...................................................................................................... 5 3.1. BubbleSort ..................................................................................................................... 6 3.2. SelectionSort ................................................................................................................. 9 3.3. InsertionSort................................................................................................................ 12 3.4. MergeSort ................................................................................................................... 15 3.5. QuickSort ..................................................................................................................... 21 4. Execução dos testes automatizados ................................................................................... 24 5. Estatísticas entre os algoritmos de ordenação ................................................................... 27 6. Conclusão ............................................................................................................................ 30
  • 3. 1. Introdução Este relatório tem como objetivo detalhar o desenvolvimento dos algoritmos de ordenação bubblesort, selectionsort, insertionsort, mergesort e quicksort. Os algoritmos foram desenvolvidos em C# utilizando a IDE Visual Studio 2010, .Net Framework 4.0, testes automatizados e orientação a aspectos. A solução criada possui dois projetos. Um deles é responsável por implementar os algoritmos de ordenação e o outro responsável apenas pelos testes. Ao apresentar cada algoritmo de ordenação, é resumido seu funcionamento e detalhado o código fonte em C#, que aparece logo em seguida, juntamente com os códigos dos testes automatizados. Ao final foram feitas estatísticas de desempenho comparando os algoritmos, descritos acima, para ver o tempo de ordenação, de cada um, em um vetor de mil posições. Todos os códigos fontes estão em formas de texto exceto por duas imagens, prints dos códigos. Isto acontece, pois foi utilizado um recurso chamado “region” que permite separar e organizar melhor o código, podendo ocultar ou exibir trechos de códigos. Os prints foram tirados para mostrar o código desejado juntamente com os regions “fechados”, que serão “abertos” e explicados na sequência.
  • 4. 2. Ferramentas e métodos utilizados Para o desenvolvimento dos algoritmos foi utilizado o seguinte ambiente:  Microsoft Visual Studio 2010;  Microsoft .Net Framework 4.0 com a linguagem C#;  Testes automatizados;  Orientação a aspectos; Os testes automatizados foram de dois tipos unitários e integrados. Isto devido à complexidade de testar alguns métodos e de o autor não querer colocar mocks para não complicar mais os programas. A programação orientada a aspectos – POA – é um paradigma de desenvolvimento que possibilita implementar funcionalidades que se encontram espalhadas por toda aplicação (crosscutting concern) de forma encapsulada e modularizada. Dentro do .Net Framework um dos princípios do POA é chamado de extension methods que consiste em desenvolver um algoritmo separado de seu objeto de uso e armazená-lo junto aos demais métodos do Framework, para ser usado a qualquer momento de qualquer lugar da solução que utilize a biblioteca em questão. Um exemplo de extension method, seria criar um método chamado ToShortString() para conversão de um datetime (1/12/2999 00:00:00) para uma data curta (01/12/20999). Ao criar este método informamos que será aplicado ao tipo datetime, logo os objetos datetime terão mais um método (ToShortString()) podendo ser usado de qualquer parte da solução e a qualquer momento. Exemplo de uso do método acima: DateTime date = DateTime.Now; String shortDate = date.ToShortString(); Se não utilizar um extension method, o modo convencional seria criar um método que recebe-se como parâmetro um datetime e retorna-se uma string. Como é apenas um algoritmo de conversão, poderia estar em uma classe estática chamada DateConvertionHelper. Veja um exemplo de uso: DateTime date = DateTime.Now; String shortDate = DateConvertionHelper.ToShortString(date); Usar um extension method torna muito mais simples a utilização final.
  • 5. 3. Algoritmos de ordenação Para não tornar o relatório longo e ser o mais objetivo possível, cada tópico de algoritmo será dividido em 3 partes:  Objetivo;  Algoritmo;  Testes. Para mais informações sobre os testes, veja o item “4. Execução dos testes automatizados”. Foi criada uma classe chamada SortingAlgorithms que contém os 6 algoritmos de ordenação. O escopo desta classe está abaixo e o conteúdo dos “regions” estão detalhados em cada algoritmo.
  • 6. 3.1. BubbleSort Objetivo: Percorrer o vetor diversas vezes e a cada passagem fazer flutuar para o final do vetor o item de maior valor. A cada passagem é analisado a quantidade de itens do vetor menos um, pois o último já estará ordenado. Algoritmo: #region BubbleSort public static void BubbleSort(this IList<int> list) { int lastListPosition = list.Count - 1; bool hasChanged = true; while (hasChanged) { hasChanged = false; for (int i = 0; i < lastListPosition; i++) { if (list[i] > list[i + 1]) { var aux = list[i]; list[i] = list[i + 1]; list[i + 1] = aux; hasChanged = true; } } lastListPosition--; } } #endregion
  • 7. Testes: using System.Linq; using Lorival.Collections; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace Tester { [TestClass] public class BubbleSortTestar : AbstractTester { [TestMethod] public void BubbleSortTestar_SortTwoItems() { //-- Arrange int[] expected = { 1, 2 }; int[] actual = { 2, 1 }; //-- Act actual.BubbleSort(); //-- Assert CollectionAssert.AreEqual(expected, actual); } [TestMethod] public void BubbleSortTestar_SortFiveItemsNeedTwoSteps() { //-- Arrange int[] expected = { 1, 2, 3, 4, 5 }; int[] actual = { 2, 1, 4, 5, 3 }; //-- Act actual.BubbleSort(); //-- Assert CollectionAssert.AreEqual(expected, actual); } [TestMethod] public void BubbleSortTestar_SortFiveItemsNeedThreeSteps() { //-- Arrange int[] expected = { 10, 12, 35, 43, 101 }; int[] actual = { 101, 35, 12, 10, 43 }; //-- Act actual.BubbleSort(); //-- Assert CollectionAssert.AreEqual(expected, actual); } [TestMethod] public void BubbleSortTestar_SortTenItems() { //-- Arrange
  • 8. int[] expected = { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 }; int[] actual = { 14, 10, 20, 12, 4, 8, 2, 16, 18, 6 }; //-- Act actual.BubbleSort(); //-- Assert CollectionAssert.AreEqual(expected, actual); } [TestMethod] public void BubbleSortTestar_SortTenItemsWithRepetedValues() { //-- Arrange int[] expected = { 2, 4, 4, 8, 10, 12, 14, 16, 18, 20 }; int[] actual = { 14, 10, 20, 12, 4, 8, 2, 16, 18, 4 }; //-- Act actual.BubbleSort(); //-- Assert CollectionAssert.AreEqual(expected, actual); } [TestMethod] public void BubbleSortTestar_SortOneHumdredItems() { //-- Arrange NumericListCreator numericListCreator = new NumericListCreator(100); int[] actual = numericListCreator.UnorderedList.ToArray<int>(); //-- Act actual.BubbleSort(); //-- Assert CollectionAssert.AreEqual(numericListCreator.OrderedList, actual); } } }
  • 9. 3.2. SelectionSort Objetivo: Percorrer o vetor diversas vezes e a cada passagem trazer para a primeira posição do vetor o item de menor valor. A cada passagem é analisado a quantidade de itens do vetor menos um, pois o primeiro já estará ordenado. A grande diferença do selectionsort para o bubblesort é que o bubble faz varias trocas a cada passagem e a seleção procura o menor valor e faz apenas uma troca no final da passagem. Algoritmo: #region SelectionSort public static void SelectionSort(this IList<int> list) { int lowestValuePosition = 0; for (int lastPosition = 0; lastPosition < list.Count; lastPosition++) { lowestValuePosition = lastPosition; for (int currentPosition = lastPosition; currentPosition < list.Count; currentPosition++) { if (list[currentPosition] < list[lowestValuePosition]) lowestValuePosition = currentPosition; } if (lowestValuePosition > lastPosition) { var aux = list[lastPosition]; list[lastPosition] = list[lowestValuePosition]; list[lowestValuePosition] = aux; } } } #endregion
  • 10. Testes: using System.Linq; using Lorival.Collections; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace Tester { [TestClass] public class SelectionSortTester : AbstractTester { [TestMethod] public void SelectionSortTester_SortTwoItems() { //-- Arrange int[] expected = { 1, 2 }; int[] actual = { 2, 1 }; //-- Act actual.SelectionSort(); //-- Assert CollectionAssert.AreEqual(expected, actual); } [TestMethod] public void SelectionSortTester_SortFiveItems() { //-- Arrange int[] expected = { 1, 2, 3, 4, 5 }; int[] actual = { 2, 1, 4, 5, 3 }; //-- Act actual.SelectionSort(); //-- Assert CollectionAssert.AreEqual(expected, actual); } [TestMethod] public void SelectionSortTester_SortFiveItemsInOtherOrder() { //-- Arrange int[] expected = { 10, 12, 35, 43, 101 }; int[] actual = { 101, 35, 12, 10, 43 }; //-- Act actual.SelectionSort(); //-- Assert CollectionAssert.AreEqual(expected, actual); } [TestMethod] public void SelectionSortTester_SortTenItems() { //-- Arrange
  • 11. int[] expected = { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 }; int[] actual = { 14, 10, 20, 12, 4, 8, 2, 16, 18, 6 }; //-- Act actual.SelectionSort(); //-- Assert CollectionAssert.AreEqual(expected, actual); } [TestMethod] public void SelectionSortTester_SortTenItemsWithRepetedValues() { //-- Arrange int[] expected = { 2, 4, 4, 8, 10, 12, 14, 16, 18, 20 }; int[] actual = { 14, 10, 20, 12, 4, 8, 2, 16, 18, 4 }; //-- Act actual.SelectionSort(); //-- Assert CollectionAssert.AreEqual(expected, actual); } [TestMethod] public void SelectionSortTester_SortOneHumdredItems() { //-- Arrange NumericListCreator numericListCreator = new NumericListCreator(100); int[] actual = numericListCreator.UnorderedList.ToArray<int>(); //-- Act actual.SelectionSort(); //-- Assert CollectionAssert.AreEqual(numericListCreator.OrderedList, actual); } } }
  • 12. 3.3. InsertionSort Objetivo: Percorrer o vetor da esquerda para a direita e à medida que avança vai deixando os elementos mais a esquerda ordenados. A cada passagem vai abrindo espaço para o item corrente e procurando, mais a esquerda qual é o lugar daquele item. Ao encontrar empurra todos os itens para a direita e insere o item selecionado no seu respectivo local. Algoritmo: #region InsertionSort public static void InsertionSort(this IList<int> list) { int valueWillBeInserted, lastPosition; for (int currentPosition = 1; currentPosition < list.Count; currentPosition++) { valueWillBeInserted = list[currentPosition]; lastPosition = currentPosition - 1; while (lastPosition >= 0 && list[lastPosition] > valueWillBeInserted) { list[lastPosition + 1] = list[lastPosition]; lastPosition--; } list[lastPosition + 1] = valueWillBeInserted; } } #endregion
  • 13. Testes: using System.Linq; using Lorival.Collections; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace Tester { [TestClass] public class InsertionSortTester : AbstractTester { [TestMethod] public void InsertionSortTester_SortTwoItems() { //-- Arrange int[] expected = { 1, 2 }; int[] actual = { 2, 1 }; //-- Act actual.InsertionSort(); //-- Assert CollectionAssert.AreEqual(expected, actual); } [TestMethod] public void InsertionSortTester_SortFiveItems() { //-- Arrange int[] expected = { 1, 2, 3, 4, 5 }; int[] actual = { 2, 1, 4, 5, 3 }; //-- Act actual.InsertionSort(); //-- Assert CollectionAssert.AreEqual(expected, actual); } [TestMethod] public void InsertionSortTester_SortFiveItemsInOtherOrder() { //-- Arrange int[] expected = { 10, 12, 35, 43, 101 }; int[] actual = { 101, 35, 12, 10, 43 }; //-- Act actual.InsertionSort(); //-- Assert CollectionAssert.AreEqual(expected, actual); } [TestMethod] public void InsertionSortTester_SortTenItems() { //-- Arrange
  • 14. int[] expected = { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 }; int[] actual = { 14, 10, 20, 12, 4, 8, 2, 16, 18, 6 }; //-- Act actual.InsertionSort(); //-- Assert CollectionAssert.AreEqual(expected, actual); } [TestMethod] public void InsertionSortTester_SortTenItemsWithRepetedValues() { //-- Arrange int[] expected = { 2, 4, 4, 8, 10, 12, 14, 16, 18, 20 }; int[] actual = { 14, 10, 20, 12, 4, 8, 2, 16, 18, 4 }; //-- Act actual.InsertionSort(); //-- Assert CollectionAssert.AreEqual(expected, actual); } [TestMethod] public void InsertionSortTester_SortOneHumdredItems() { //-- Arrange NumericListCreator numericListCreator = new NumericListCreator(100); int[] actual = numericListCreator.UnorderedList.ToArray<int>(); //-- Act actual.InsertionSort(); //-- Assert CollectionAssert.AreEqual(numericListCreator.OrderedList, actual); } } }
  • 15. 3.4. MergeSort Objetivo: Criar uma sequência ordenada baseada em outras duas também ordenadas. Para isto é necessário dividir a sequência original até chegar a um limite ordenável por um insertionSort (100 itens neste exemplo) ou até sobrarem pares para ordenar. Depois vai agrupando todas as sequências divididas até formar a sequência ordenada. Modo com InsertionSort e sem InsertionSort Foi desenvolvido dois métodos de chamada. Um para mergeSort com InsertionSort e outro sem InsertionSort. Ambos utilizam o mesmo algoritmo para ordenação com a diferença de um parâmetro que informa se irá usar o algoritmo InsertionSort quando chegar nos 100 itens ou não.
  • 16. Algoritmo: #region Private Methods private static IList<int> ExecuteMergeSort(IList<int> list, bool sortWithInsertionSort) { if (sortWithInsertionSort) { if (list.Count <= 100) { list.InsertionSort(); return list; } } else if (list.Count <= 1) return list; int midlePosition = list.Count / 2; IList<int> leftSide = new List<int>(); IList<int> rightSide = new List<int>(); for (int i = 0; i < midlePosition; i++) leftSide.Add(list[i]); for (int i = midlePosition; i < list.Count; i++) rightSide.Add(list[i]); return ExecuteMergeSort(ExecuteMergeSort(leftSide, sortWithInsertionSort), ExecuteMergeSort(rightSide, sortWithInsertionSort)); } private static IList<int> ExecuteMergeSort(IList<int> left, IList<int> right) { IList<int> listToBeReturned = new List<int>(); while (left.Count > 0 && right.Count > 0) if (left[0] > right[0]) { listToBeReturned.Add(right[0]); right.RemoveAt(0); } else { listToBeReturned.Add(left[0]); left.RemoveAt(0); } for (int i = 0; i < left.Count; i++) listToBeReturned.Add(left[i]); for (int i = 0; i < right.Count; i++) listToBeReturned.Add(right[i]); return listToBeReturned; } #endregion
  • 17. Testes: using System.Linq; using Lorival.Collections; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace Tester { [TestClass] public class MergeTester : AbstractTester { #region WithOutInsertionSort [TestMethod] public void MergeTester_SortTwoItems() { //-- Arrange int[] expected = { 1, 2 }; int[] actual = { 2, 1 }; //-- Act actual.MergeSort(); //-- Assert CollectionAssert.AreEqual(expected, actual); } [TestMethod] public void MergeTester_SortFiveItems() { //-- Arrange int[] expected = { 1, 2, 3, 4, 5 }; int[] actual = { 2, 1, 4, 5, 3 }; //-- Act actual.MergeSort(); //-- Assert CollectionAssert.AreEqual(expected, actual); } [TestMethod] public void MergeTester_SortFiveItemsInOtherOrder() { //-- Arrange int[] expected = { 10, 12, 35, 43, 101 }; int[] actual = { 101, 35, 12, 10, 43 }; //-- Act actual.MergeSort(); //-- Assert CollectionAssert.AreEqual(expected, actual); } [TestMethod] public void MergeTester_SortTenItems() {
  • 18. //-- Arrange int[] expected = { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 }; int[] actual = { 14, 10, 20, 12, 4, 8, 2, 16, 18, 6 }; //-- Act actual.MergeSort(); //-- Assert CollectionAssert.AreEqual(expected, actual); } [TestMethod] public void MergeTester_SortTenItemsWithRepetedValues() { //-- Arrange int[] expected = { 2, 4, 4, 8, 10, 12, 14, 16, 18, 20 }; int[] actual = { 14, 10, 20, 12, 4, 8, 2, 16, 18, 4 }; //-- Act actual.MergeSort(); //-- Assert CollectionAssert.AreEqual(expected, actual); } [TestMethod] public void MergeTester_SortOneHumdredItems() { //-- Arrange NumericListCreator numericListCreator = new NumericListCreator(100); int[] actual = numericListCreator.UnorderedList.ToArray<int>(); //-- Act actual.MergeSort(); //-- Assert CollectionAssert.AreEqual(numericListCreator.OrderedList, actual); } #endregion #region WithInsertionSort [TestMethod] public void MergeTester_SortTwoItems_WithInsertionSort() { //-- Arrange int[] expected = { 1, 2 }; int[] actual = { 2, 1 }; //-- Act actual.MergeSortWithInsertionSort(); //-- Assert CollectionAssert.AreEqual(expected, actual); } [TestMethod] public void MergeTester_SortFiveItems_WithInsertionSort()
  • 19. { //-- Arrange int[] expected = { 1, 2, 3, 4, 5 }; int[] actual = { 2, 1, 4, 5, 3 }; //-- Act actual.MergeSortWithInsertionSort(); //-- Assert CollectionAssert.AreEqual(expected, actual); } [TestMethod] public void MergeTester_SortFiveItemsInOtherOrder_WithInsertionSort() { //-- Arrange int[] expected = { 10, 12, 35, 43, 101 }; int[] actual = { 101, 35, 12, 10, 43 }; //-- Act actual.MergeSortWithInsertionSort(); //-- Assert CollectionAssert.AreEqual(expected, actual); } [TestMethod] public void MergeTester_SortTenItems_WithInsertionSort() { //-- Arrange int[] expected = { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 }; int[] actual = { 14, 10, 20, 12, 4, 8, 2, 16, 18, 6 }; //-- Act actual.MergeSortWithInsertionSort(); //-- Assert CollectionAssert.AreEqual(expected, actual); } [TestMethod] public void MergeTester_SortTenItemsWithRepetedValues_WithInsertionSort() { //-- Arrange int[] expected = { 2, 4, 4, 8, 10, 12, 14, 16, 18, 20 }; int[] actual = { 14, 10, 20, 12, 4, 8, 2, 16, 18, 4 }; //-- Act actual.MergeSortWithInsertionSort(); //-- Assert CollectionAssert.AreEqual(expected, actual); } [TestMethod] public void MergeTester_SortOneHumdredItems_WithInsertionSort() {
  • 20. //-- Arrange NumericListCreator numericListCreator = new NumericListCreator(100); int[] actual = numericListCreator.UnorderedList.ToArray<int>(); //-- Act actual.MergeSortWithInsertionSort(); //-- Assert CollectionAssert.AreEqual(numericListCreator.OrderedList, actual); } #endregion } }
  • 21. 3.5. QuickSort Objetivo: Ordena o vetor dividindo-o recursivamente, através de um pivô, colocando os itens menores que o pivô de um lado e maiores do outro. Ao final os itens estarão ordenados. Este é o algoritmo mais rápido e eficiente para ordenação para vetores grandes. Algoritmo: #region QuickSort public static void QuickSort(this IList<int> list) { Sort(list, 0, list.Count - 1); } #region Private Methods private static void Sort(IList<int> list, int startPosition, int endPosition) { if (startPosition < endPosition) { int pivotPosition = Partition(list, startPosition, endPosition); Sort(list, startPosition, pivotPosition - 1); Sort(list, pivotPosition + 1, endPosition); } } private static int Partition(IList<int> list, int startPosition, int endPosition) { int pivo = list[startPosition]; int startPartitionPosition = startPosition + 1, endPartitionPosition = endPosition; while (startPartitionPosition <= endPartitionPosition) { if (list[startPartitionPosition] <= pivo) startPartitionPosition++; else if (pivo < list[endPartitionPosition]) endPartitionPosition--; else { int troca = list[startPartitionPosition]; list[startPartitionPosition] = list[endPartitionPosition]; list[endPartitionPosition] = troca; startPartitionPosition++; endPartitionPosition--; } } list[startPosition] = list[endPartitionPosition]; list[endPartitionPosition] = pivo; return endPartitionPosition; } #endregion #endregion
  • 22. Testes: using System.Linq; using Lorival.Collections; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace Tester { [TestClass] public class QuickSortTester : AbstractTester { [TestMethod] public void QuickSortTester_SortTwoItems() { //-- Arrange int[] expected = { 1, 2 }; int[] actual = { 2, 1 }; //-- Act actual.QuickSort(); //-- Assert CollectionAssert.AreEqual(expected, actual); } [TestMethod] public void QuickSortTester_SortFiveItems() { //-- Arrange int[] expected = { 1, 2, 3, 4, 5 }; int[] actual = { 2, 1, 4, 5, 3 }; //-- Act actual.QuickSort(); //-- Assert CollectionAssert.AreEqual(expected, actual); } [TestMethod] public void QuickSortTester_SortFiveItemsInOtherOrder() { //-- Arrange int[] expected = { 10, 12, 35, 43, 101 }; int[] actual = { 101, 35, 12, 10, 43 }; //-- Act actual.QuickSort(); //-- Assert CollectionAssert.AreEqual(expected, actual); } [TestMethod] public void QuickSortTester_SortTenItems() { //-- Arrange
  • 23. int[] expected = { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 }; int[] actual = { 14, 10, 20, 12, 4, 8, 2, 16, 18, 6 }; //-- Act actual.QuickSort(); //-- Assert CollectionAssert.AreEqual(expected, actual); } [TestMethod] public void QuickSortTester_SortTenItemsWithRepetedValues() { //-- Arrange int[] expected = { 2, 4, 4, 8, 10, 12, 14, 16, 18, 20 }; int[] actual = { 14, 10, 20, 12, 4, 8, 2, 16, 18, 4 }; //-- Act actual.QuickSort(); //-- Assert CollectionAssert.AreEqual(expected, actual); } [TestMethod] public void QuickSortTester_SortOneHumdredItems() { //-- Arrange NumericListCreator numericListCreator = new NumericListCreator(100); int[] actual = numericListCreator.UnorderedList.ToArray<int>(); //-- Act actual.QuickSort(); //-- Assert CollectionAssert.AreEqual(numericListCreator.OrderedList, actual); } } }
  • 24. 4. Execução dos testes automatizados Para facilitar os testes automatizados para grandes vetores foi criado uma classe chamada NumericListCreator que tem como objetivo criar dois vetores iguais com a diferença que um está ordenado e o outro não. Quando criamos a instância desta classe informamos o tamanho do vetor que queremos e ela disponibiliza duas propriedades, cada uma sendo um vetor. Para criar os dois vetores com os mesmos valores, foi utilizado um recurso do .Net Framework. Na verdade é um objeto chamado SortedList, que nada mais é do que uma lista que se ordena conforme vai incluindo os itens. Esta classe gera os vetores com no máximo cem mil posições. Veja abaixo a codificação desta classe: using System.Collections; using System.Collections.Generic; using Lorival.Collections; using System; namespace Tester { internal class NumericListCreator { internal IList OrderedList { get; private set; } internal IList<int> UnorderedList { get; private set; } private const int limitGeneratedLists = 100000; internal NumericListCreator(int listSize) { OrderedList = new List<int>(); UnorderedList = new List<int>(); if (listSize > limitGeneratedLists) listSize = limitGeneratedLists; SortedList sortedList = new SortedList(); while(sortedList.Count < listSize) { int randowNumber = new Random().Next(limitGeneratedLists); if (!sortedList.ContainsKey(randowNumber)) { sortedList.Add(randowNumber, null); UnorderedList.Add(randowNumber); } } OrderedList = sortedList.GetKeyList(); } } }
  • 25. Todos os testes foram escritos seguindo um pouco de babysteps. Começam com vetores de duas posições e vai aumentando até um vetor de 100 posições, gerado através do objeto gerador de vetores já citado. Foi criada uma classe abstrata para os testes. Esta tem como único objetivo armazenar informações pertinentes ao framework de testes. Veja abaixo: using Microsoft.VisualStudio.TestTools.UnitTesting; namespace Tester { public abstract class AbstractTester { /// <summary> ///Gets or sets the test context which provides ///information about and functionality for the current test run. ///</summary> public TestContext TestContext { get;set;} #region Additional test attributes // // You can use the following additional attributes as you write your tests: // // Use ClassInitialize to run code before running the first test in the class // [ClassInitialize()] // public static void MyClassInitialize(TestContext testContext) { } // // Use ClassCleanup to run code after all tests in a class have run // [ClassCleanup()] // public static void MyClassCleanup() { } // // Use TestInitialize to run code before running each test // [TestInitialize()] // public void MyTestInitialize() { } // // Use TestCleanup to run code after each test has run // [TestCleanup()] // public void MyTestCleanup() { } // #endregion } }
  • 26. Abaixo segue o resultado da execução de todos os 36 testes.
  • 27. 5. Estatísticas entre os algoritmos de ordenação Abaixo segue tabelas comparando o tempo de execução dos algoritmos ordenando vetores. Para a realização dos testes foi gerado um vetor com valores aleatórios e utilizado o mesmo vetor para todos os algoritmos. O programa utilizado será explicado após as tabelas de comparação. Ordenando vetores com 10 itens BubbleSort {00:00:00} SelectionSort {00:00:00.0010001} InsertionSort {00:00:00} MergeSort {00:00:00.0020002} MergeSortWithInsertionSort {00:00:00} QuickSort {00:00:00.0010001} Ordenando vetores com 100 itens BubbleSort {00:00:00.0012501} SelectionSort {00:00:00.0010001} InsertionSort {00:00:00.0012501} MergeSort {00:00:00.0012501} MergeSortWithInsertionSort {00:00:00.0012501} QuickSort {00:00:00.0012500} Ordenando vetores com 1000 itens BubbleSort {00:00:00.0179982} SelectionSort {00:00:00.0109989} InsertionSort {00:00:00.0069993} MergeSort {00:00:00.0029997} MergeSortWithInsertionSort {00:00:00.0019998} QuickSort {00:00:00.0019998} Ordenando vetores com 10000 itens BubbleSort {00:00:01.6988304} SelectionSort {00:00:01.0148985} InsertionSort {00:00:00.6489351} MergeSort {00:00:00.0749925} MergeSortWithInsertionSort {00:00:00.0569943} QuickSort {00:00:00.0059994}
  • 28. Ordenando vetores com 50000 itens BubbleSort {00:00:41.9553894} SelectionSort {00:00:28.3195700} InsertionSort {00:00:16.4596458} MergeSort {00:00:01.2951295} MergeSortWithInsertionSort {00:00:01.1681168} QuickSort {00:00:00.0280028} Para implementar os extensions methods (orientação a aspectos) é necessário utilizar classes estáticas. Estas por sua vez não permite herdar de interfaces o que inviabiliza a aplicação do command pattern. Pela ótica de como foi desenvolvido, o projeto responsável por contemplar o programa que gera as estatísticas foi o projeto de testes, visto que as estatísticas, neste caso, fazem parte dos testes de avaliação do software. Abaixo segue a classe que gerou as estatísticas apresentadas: using System; using System.Linq; using Lorival.Collections; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace Tester { [TestClass] public class SpeedTester : AbstractTester { [TestMethod] public void EffectTest() { DateTime startTime; DateTime endTime; startTime = DateTime.Now; NumericListCreator numericListCreator = new NumericListCreator(50000); endTime = DateTime.Now; TimeSpan numericListCreatorSpeedTime = endTime - startTime; startTime = DateTime.Now; int[] bubble = numericListCreator.UnorderedList.ToArray<int>(); bubble.BubbleSort(); endTime = DateTime.Now; TimeSpan bubbleSpeedTime = endTime - startTime; //-- startTime = DateTime.Now; int[] selection = numericListCreator.UnorderedList.ToArray<int>(); selection.SelectionSort(); endTime = DateTime.Now; TimeSpan selectionSpeedTime = endTime - startTime; //-- startTime = DateTime.Now;
  • 29. int[] insertion = numericListCreator.UnorderedList.ToArray<int>(); insertion.InsertionSort(); endTime = DateTime.Now; TimeSpan insertionSpeedTime = endTime - startTime; //-- startTime = DateTime.Now; int[] merge = numericListCreator.UnorderedList.ToArray<int>(); merge.MergeSort(); endTime = DateTime.Now; TimeSpan mergeSpeedTime = endTime - startTime; //-- startTime = DateTime.Now; int[] mergeWithInsertion = numericListCreator.UnorderedList.ToArray<int>(); mergeWithInsertion.MergeSortWithInsertionSort(); endTime = DateTime.Now; TimeSpan mergeWithInsertionSpeedTime = endTime - startTime; //-- startTime = DateTime.Now; int[] quick = numericListCreator.UnorderedList.ToArray<int>(); quick.QuickSort(); endTime = DateTime.Now; TimeSpan quickSpeedTime = endTime - startTime; } } }
  • 30. 6. Conclusão Os objetivos do trabalho foram alcançados com sucesso, ou seja, foi possível construir todos os algoritmos e apresenta-los neste relatório juntamente com estatísticas de desempenho de cada um. O tempo aproximado total utilizado para desenvolvimento e geração deste relatório foi de doze horas. Os testes unitários foram imprescindíveis para a perfeita conclusão de todos os algoritmos. Mesmo depois de concluído cada um, foi necessário passar por uma fase de revisão e refinação o que permitiu serem feitas de forma muito mais rápidas e assertivas, visto que existiam testes validando a ordenação de todos os algoritmos. O maior problema encontrado foi na geração de um vetor não ordenado com valores aleatórios para a realização dos testes. Como esta era uma responsabilidade do projeto de testes foi possível utilizar o “SortedList” para facilitar o desenvolvimento, porém o tempo para geração de um vetor de 50 mil posições sem valores repetidos foi de quase 20 minutos. Existem várias outras formas de gerar este vetor, porém como não fazia parte dos objetivos propostos e fazia parte apenas dos testes foi utilizada a forma mais rápida de desenvolver, que implicou unicamente em ter maior tempo de espera na geração das estatísticas. Por fim o trabalho foi de grande valia para entendimento, principalmente, das diferenças de desempenho entre os algoritmos de ordenação e compreender que sempre existem métodos mais eficientes de resolver um problema recorrente.