SlideShare uma empresa Scribd logo
1 de 30
Baixar para ler offline
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.

Mais conteúdo relacionado

Mais procurados

Complexidade de algoritmos insertion, selection e bubble sort.
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 Rocha
 
1.1 elementos en el paradigma orientado a objetos
1.1 elementos en el paradigma orientado a objetos1.1 elementos en el paradigma orientado a objetos
1.1 elementos en el paradigma orientado a objetosCirino Silva tovar
 
Inserindo em Ordem Crescente na Lista Encadeada
Inserindo em Ordem Crescente na Lista EncadeadaInserindo em Ordem Crescente na Lista Encadeada
Inserindo em Ordem Crescente na Lista EncadeadaElaine Cecília Gatto
 
Ordenação de vetores
Ordenação de vetoresOrdenação de vetores
Ordenação de vetoresalfredtaddeus
 
Estrutura de Dados - Aula 12 - Pesquisa de Dados (Sequencial e Binária)
Estrutura de Dados - Aula 12 - Pesquisa de Dados (Sequencial e Binária)Estrutura de Dados - Aula 12 - Pesquisa de Dados (Sequencial e Binária)
Estrutura de Dados - Aula 12 - Pesquisa de Dados (Sequencial e Binária)Leinylson Fontinele
 
Metodos de-ordenamiento
Metodos de-ordenamientoMetodos de-ordenamiento
Metodos de-ordenamientodeff000001
 
Las estructuras de control en programación presentacion
Las estructuras de control en programación presentacionLas estructuras de control en programación presentacion
Las estructuras de control en programación presentacionOrangel4
 
Calculadora Gráfica Java implementando el Patrón MVC
Calculadora Gráfica Java implementando el Patrón MVCCalculadora Gráfica Java implementando el Patrón MVC
Calculadora Gráfica Java implementando el Patrón MVCIgnacio Aular Reyes
 
Control de eventos en gui
Control de eventos en guiControl de eventos en gui
Control de eventos en guijc_lovecraft77
 
Metodos de ordenamiento 2
Metodos de ordenamiento 2Metodos de ordenamiento 2
Metodos de ordenamiento 2angela montilla
 
Método de ordenamiento por selección (selection sort
Método de ordenamiento por selección (selection sortMétodo de ordenamiento por selección (selection sort
Método de ordenamiento por selección (selection sortlinkinpark03
 
Método de ordenamiento shell
Método de ordenamiento shellMétodo de ordenamiento shell
Método de ordenamiento shellUDG
 
Estrutura de Dados - Aula 02 - Estrutura de Dados e TAD
Estrutura de Dados - Aula 02 - Estrutura de Dados e TADEstrutura de Dados - Aula 02 - Estrutura de Dados e TAD
Estrutura de Dados - Aula 02 - Estrutura de Dados e TADLeinylson Fontinele
 

Mais procurados (20)

Algoritmo Shell Sort
Algoritmo Shell SortAlgoritmo Shell Sort
Algoritmo Shell Sort
 
Bubble Sort
Bubble SortBubble Sort
Bubble Sort
 
Complexidade de algoritmos insertion, selection e bubble sort.
Complexidade de algoritmos insertion, selection e bubble sort.Complexidade de algoritmos insertion, selection e bubble sort.
Complexidade de algoritmos insertion, selection e bubble sort.
 
1.1 elementos en el paradigma orientado a objetos
1.1 elementos en el paradigma orientado a objetos1.1 elementos en el paradigma orientado a objetos
1.1 elementos en el paradigma orientado a objetos
 
Inserindo em Ordem Crescente na Lista Encadeada
Inserindo em Ordem Crescente na Lista EncadeadaInserindo em Ordem Crescente na Lista Encadeada
Inserindo em Ordem Crescente na Lista Encadeada
 
Ordenação de vetores
Ordenação de vetoresOrdenação de vetores
Ordenação de vetores
 
Metodos de ordenamiento
Metodos de ordenamientoMetodos de ordenamiento
Metodos de ordenamiento
 
Estrutura de Dados - Aula 12 - Pesquisa de Dados (Sequencial e Binária)
Estrutura de Dados - Aula 12 - Pesquisa de Dados (Sequencial e Binária)Estrutura de Dados - Aula 12 - Pesquisa de Dados (Sequencial e Binária)
Estrutura de Dados - Aula 12 - Pesquisa de Dados (Sequencial e Binária)
 
Metodos de-ordenamiento
Metodos de-ordenamientoMetodos de-ordenamiento
Metodos de-ordenamiento
 
Tabela Hash
Tabela HashTabela Hash
Tabela Hash
 
Las estructuras de control en programación presentacion
Las estructuras de control en programación presentacionLas estructuras de control en programación presentacion
Las estructuras de control en programación presentacion
 
Calculadora Gráfica Java implementando el Patrón MVC
Calculadora Gráfica Java implementando el Patrón MVCCalculadora Gráfica Java implementando el Patrón MVC
Calculadora Gráfica Java implementando el Patrón MVC
 
Control de eventos en gui
Control de eventos en guiControl de eventos en gui
Control de eventos en gui
 
Metodos de ordenamiento 2
Metodos de ordenamiento 2Metodos de ordenamiento 2
Metodos de ordenamiento 2
 
Método de ordenamiento por selección (selection sort
Método de ordenamiento por selección (selection sortMétodo de ordenamiento por selección (selection sort
Método de ordenamiento por selección (selection sort
 
Método de ordenamiento shell
Método de ordenamiento shellMétodo de ordenamiento shell
Método de ordenamiento shell
 
Heap sort
Heap sortHeap sort
Heap sort
 
Algoritmo 06 - Array e Matrizes
Algoritmo 06 - Array e MatrizesAlgoritmo 06 - Array e Matrizes
Algoritmo 06 - Array e Matrizes
 
Estrutura de Dados - Aula 02 - Estrutura de Dados e TAD
Estrutura de Dados - Aula 02 - Estrutura de Dados e TADEstrutura de Dados - Aula 02 - Estrutura de Dados e TAD
Estrutura de Dados - Aula 02 - Estrutura de Dados e TAD
 
Algoritmos de busca
Algoritmos de buscaAlgoritmos de busca
Algoritmos de busca
 

Destaque

Análise de Algoritmos de Ordenação Interna
Análise de Algoritmos de Ordenação InternaAnálise de Algoritmos de Ordenação Interna
Análise de Algoritmos de Ordenação InternaJohnnatan Messias
 
Comparação Experimental de Algoritmos de Ordenação
Comparação Experimental de Algoritmos de OrdenaçãoComparação Experimental de Algoritmos de Ordenação
Comparação Experimental de Algoritmos de OrdenaçãoLenon Fachiano
 
Ordenação de Dados por Distribuição de Chaves
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
 
Análise empírica de algoritmos de ordenação
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
 
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...
Complexidade de Algoritmos, Notação assintótica, Algoritmos polinomiais e in...Universidade de São Paulo
 
métodos ordenação C, bolha, selection sort e insertion sort
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
 
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!
Faça Apresentações! Não Faça Slides!Victor Gonçalves
 

Destaque (7)

Análise de Algoritmos de Ordenação Interna
Análise de Algoritmos de Ordenação InternaAnálise de Algoritmos de Ordenação Interna
Análise de Algoritmos de Ordenação Interna
 
Comparação Experimental de Algoritmos de Ordenação
Comparação Experimental de Algoritmos de OrdenaçãoComparação Experimental de Algoritmos de Ordenação
Comparação Experimental de Algoritmos de Ordenação
 
Ordenação de Dados por Distribuição de Chaves
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 Chaves
 
Análise empírica de algoritmos de ordenação
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
 
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...
Complexidade de Algoritmos, Notação assintótica, Algoritmos polinomiais e in...
 
métodos ordenação C, bolha, selection sort e insertion sort
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
 
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!
Faça Apresentações! Não Faça Slides!
 

Semelhante a case3

As Novidades Do C# 4.0 - NetPonto
As Novidades Do C# 4.0 - NetPontoAs Novidades Do C# 4.0 - NetPonto
As Novidades Do C# 4.0 - NetPontoPaulo Morgado
 
Testes em Aplicações Web com Cactus
Testes em Aplicações Web com CactusTestes em Aplicações Web com Cactus
Testes em Aplicações Web com CactusDenis L Presciliano
 
ASP.Net Módulo 2
ASP.Net   Módulo 2ASP.Net   Módulo 2
ASP.Net Módulo 2michellobo
 
Programação Desktop: Revisão Core Java
Programação Desktop: Revisão Core JavaProgramação Desktop: Revisão Core Java
Programação Desktop: Revisão Core JavaElaine Cecília Gatto
 
Maratona de Programação com STL
Maratona de Programação com STLMaratona de Programação com STL
Maratona de Programação com STLMarcos Castro
 
Refatoração de código com Capitão Nascimento versão completa
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 completaEduardo Bregaida
 
LINQ - Language Integrated Query
LINQ - Language Integrated QueryLINQ - Language Integrated Query
LINQ - Language Integrated QueryDalton Valadares
 
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)
Utilitários para Programação Concorrente em Java (2005)Helder da Rocha
 
Curso java 01 - molhando os pés com java
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 javaMaurício Linhares
 
Curso Java Básico - Aula 03
Curso Java Básico - Aula 03Curso Java Básico - Aula 03
Curso Java Básico - Aula 03Natanael Fonseca
 
Semana 4: Atribuições especiais, matrizes, ciclos, classes pacote
Semana  4: Atribuições especiais, matrizes, ciclos, classes pacoteSemana  4: Atribuições especiais, matrizes, ciclos, classes pacote
Semana 4: Atribuições especiais, matrizes, ciclos, classes pacoteManuel Menezes de Sequeira
 
Threads 08: Executores e Futures
Threads 08: Executores e FuturesThreads 08: Executores e Futures
Threads 08: Executores e FuturesHelder da Rocha
 
Lista IV de Programação Orientada a Objetos
Lista IV de Programação Orientada a ObjetosLista IV de Programação Orientada a Objetos
Lista IV de Programação Orientada a Objetosunifesptk
 
TDC2016POA | Trilha Android - Testes no Android
TDC2016POA | Trilha Android - Testes no AndroidTDC2016POA | Trilha Android - Testes no Android
TDC2016POA | Trilha Android - Testes no Androidtdc-globalcode
 

Semelhante a case3 (20)

As Novidades Do C# 4.0 - NetPonto
As Novidades Do C# 4.0 - NetPontoAs Novidades Do C# 4.0 - NetPonto
As Novidades Do C# 4.0 - NetPonto
 
ESTRUTURA DE DADOS (JAVA) AULA 09
ESTRUTURA DE DADOS (JAVA) AULA 09ESTRUTURA DE DADOS (JAVA) AULA 09
ESTRUTURA DE DADOS (JAVA) AULA 09
 
Mock Objects
Mock ObjectsMock Objects
Mock Objects
 
Threads 09: Paralelismo
Threads 09: ParalelismoThreads 09: Paralelismo
Threads 09: Paralelismo
 
Testes em Aplicações Web com Cactus
Testes em Aplicações Web com CactusTestes em Aplicações Web com Cactus
Testes em Aplicações Web com Cactus
 
ASP.Net Módulo 2
ASP.Net   Módulo 2ASP.Net   Módulo 2
ASP.Net Módulo 2
 
Programação Desktop: Revisão Core Java
Programação Desktop: Revisão Core JavaProgramação Desktop: Revisão Core Java
Programação Desktop: Revisão Core Java
 
Maratona de Programação com STL
Maratona de Programação com STLMaratona de Programação com STL
Maratona de Programação com STL
 
Refatoração de código com Capitão Nascimento versão completa
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
 
LINQ - Language Integrated Query
LINQ - Language Integrated QueryLINQ - Language Integrated Query
LINQ - Language Integrated Query
 
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)
Utilitários para Programação Concorrente em Java (2005)
 
Curso java 01 - molhando os pés com java
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
 
Curso Java Básico - Aula 03
Curso Java Básico - Aula 03Curso Java Básico - Aula 03
Curso Java Básico - Aula 03
 
Aula5
Aula5Aula5
Aula5
 
Melhorando seu App com Kotlin e Testes
Melhorando seu App com Kotlin e TestesMelhorando seu App com Kotlin e Testes
Melhorando seu App com Kotlin e Testes
 
Javascript
JavascriptJavascript
Javascript
 
Semana 4: Atribuições especiais, matrizes, ciclos, classes pacote
Semana  4: Atribuições especiais, matrizes, ciclos, classes pacoteSemana  4: Atribuições especiais, matrizes, ciclos, classes pacote
Semana 4: Atribuições especiais, matrizes, ciclos, classes pacote
 
Threads 08: Executores e Futures
Threads 08: Executores e FuturesThreads 08: Executores e Futures
Threads 08: Executores e Futures
 
Lista IV de Programação Orientada a Objetos
Lista IV de Programação Orientada a ObjetosLista IV de Programação Orientada a Objetos
Lista IV de Programação Orientada a Objetos
 
TDC2016POA | Trilha Android - Testes no Android
TDC2016POA | Trilha Android - Testes no AndroidTDC2016POA | Trilha Android - Testes no Android
TDC2016POA | Trilha Android - Testes no Android
 

Mais de Lorival Smolski Chapuis

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...
Uso de uma rede neural artificial para previsão do volume de lodo gerado em e...Lorival Smolski Chapuis
 
DotNet Framework e Orientação a Objetos 1 - Introdução
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
 
Aula inaugural da GeraçãoTec - Softville/Joinville
Aula inaugural da GeraçãoTec - Softville/JoinvilleAula inaugural da GeraçãoTec - Softville/Joinville
Aula inaugural da GeraçãoTec - Softville/JoinvilleLorival Smolski Chapuis
 
Tutorial realidade aumentada - Sociesc 2011
Tutorial realidade aumentada - Sociesc 2011Tutorial realidade aumentada - Sociesc 2011
Tutorial realidade aumentada - Sociesc 2011Lorival Smolski Chapuis
 
Coding Dojo - Aplicando Princípios Ágeis
Coding Dojo - Aplicando Princípios ÁgeisCoding Dojo - Aplicando Princípios Ágeis
Coding Dojo - Aplicando Princípios ÁgeisLorival Smolski Chapuis
 

Mais de Lorival Smolski Chapuis (9)

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...
Uso de uma rede neural artificial para previsão do volume de lodo gerado em e...
 
Joinville Dojo 2010
Joinville Dojo   2010Joinville Dojo   2010
Joinville Dojo 2010
 
Domain driven design - Visão Geral
Domain driven design - Visão GeralDomain driven design - Visão Geral
Domain driven design - Visão Geral
 
DotNet Framework e Orientação a Objetos 1 - Introdução
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ção
 
Aula inaugural da GeraçãoTec - Softville/Joinville
Aula inaugural da GeraçãoTec - Softville/JoinvilleAula inaugural da GeraçãoTec - Softville/Joinville
Aula inaugural da GeraçãoTec - Softville/Joinville
 
Tutorial realidade aumentada - Sociesc 2011
Tutorial realidade aumentada - Sociesc 2011Tutorial realidade aumentada - Sociesc 2011
Tutorial realidade aumentada - Sociesc 2011
 
Realidade Aumentada - Sociesc 2011
Realidade Aumentada - Sociesc 2011Realidade Aumentada - Sociesc 2011
Realidade Aumentada - Sociesc 2011
 
Iadis Conference Flood Forecasting
Iadis Conference   Flood ForecastingIadis Conference   Flood Forecasting
Iadis Conference Flood Forecasting
 
Coding Dojo - Aplicando Princípios Ágeis
Coding Dojo - Aplicando Princípios ÁgeisCoding Dojo - Aplicando Princípios Ágeis
Coding Dojo - Aplicando Princípios Ágeis
 

case3

  • 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.