Introdução à classificação em c #

A classificação em c # é o processo de organizar o conteúdo de uma coleção em uma ordem específica. Uma coleção pode ser uma matriz, uma lista ou qualquer outro grupo de dados. A coleção pode conter elementos de tipos simples e tipos complexos. Um tipo simples pode ser uma coleção de números inteiros, seqüências de caracteres, números de ponto flutuante, etc. Um tipo complexo pode ser uma coleção de objetos de tipos definidos pelo usuário, como Funcionário, Estudante, etc. Tipos complexos são mais do que frequentemente aninhados, o que significa os objetos podem ter vários atributos.

Exemplos

  • Tipo Simples
    • Coleção inteira - (1, 2, 3, 4, 5)
    • Coleção de strings - ("Mark", "Jamie", "Anna")
  • Tipo complexo
    • ((Nome: “Marca”, ID do funcionário: “123”, Escritório: “Londres”),
      (Nome: "Jane", ID do funcionário: "456", Escritório: "NY"),
      (Nome: "Annie", ID do funcionário: "789", Escritório: "Sydney"))

O C # forneceu métodos embutidos para classificar coleções. Seja um método Array, List ou qualquer Coleção Genérica, o método C # Sort () pode classificá-lo com base no Comparador fornecido. Internamente, a implementação .Net usa o algoritmo Quicksort para classificar coleções em C #. Discutiremos mais sobre isso nas seções subseqüentes do artigo.

Como a classificação é realizada em c #?

Conforme declarado anteriormente, a estrutura .Net usa a abordagem Quicksort para classificar os elementos em uma coleção C #. Então, o que é quicksort?

O Quicksort segue uma estratégia de dividir e conquistar. Isso significa que o algoritmo de classificação seleciona um elemento dinâmico e divide a matriz com base no elemento dinâmico. Os elementos menores que o pivô são colocados antes dele. Os elementos maiores que o pivô são colocados depois dele. Isso garante que o elemento dinâmico seja classificado. Além disso, a matriz é dividida em dois elementos menores que o pivô e elementos maiores que o pivô. Em seguida, o algoritmo segue a mesma abordagem para as duas matrizes.

Uma ilustração disso pode ser vista abaixo.

Matriz não classificada - 18, 5, 16, 23, 50, 32

Etapa 1 (Pivô = 32) - 18, 5, 16, 23, 32, 50

Etapa 2a
Matriz não classificada - 18, 5, 16, 23
Pivô = 23
Matriz parcialmente classificada - 18, 5, 16, 23

Etapa 2b
Matriz não classificada - 50
Pivô = 50
Matriz parcialmente classificada - 50

Etapa 3a
Matriz não classificada - 18, 5, 16
Pivô = 16
Matriz parcialmente classificada - 5, 16, 18

Matriz classificada - 5, 16, 18, 23, 32, 50

Assim, o Quicksort possui dois processos principais - selecionando o pivô e particionando a matriz. As implementações do algoritmo dependem da seleção do pivô. Pode ser o primeiro elemento, ou o último, ou qualquer elemento aleatório, ou a mediana da matriz. Depois que a partição é concluída e o pivô é colocado na posição correta, o algoritmo é chamado recursivamente para as matrizes particionadas, até que cada elemento seja classificado.

Quando a classificação é feita em C #, surge o conceito de Quicksort estável e instável. Em um Quicksort estável, se dois elementos forem iguais, sua ordem da matriz original será preservada. Caso contrário, é uma classificação rápida instável. A implementação de C # usa o Quicksort instável.

Tipos de classificação em c #

Nesta seção do artigo, focaríamos principalmente em dois tipos de coleções em C # - matrizes e listas. Nós nos aprofundaríamos em como o C # classifica as matrizes e listas. A próxima seção tentaria explicá-lo com alguns exemplos.

1. Classificando uma matriz em C #

Vejamos as diferentes maneiras pelas quais podemos classificar uma matriz em C #.

uma. Usando o Comparador Padrão

Este é o método Sort () padrão. Se nenhum Comparador for explicitamente passado para o método, o C # usará a ordem crescente para organizar os elementos.

Código:

using System;
public class Program
(
public static void Main()
(
String() strArray = ("I", "Am", "Learning", "Array", "Sorting", "In", "C#");
int() intArray = (23, 76, 12, 43, 90, 30);
Array.Sort(strArray);
Array.Sort(intArray);
Console.WriteLine("Sorted String Array:\n");
DisplayArray(strArray);
Console.WriteLine("\n\n\nSorted Integer Array:\n");
DisplayArray(intArray);
)
static void DisplayArray(string() arr)
(
foreach (string a in arr)
(
Console.Write(a + "\t");
)
)
static void DisplayArray(int() arr)
(
foreach (int a in arr)
(
Console.Write(a + "\t");
)
)
)

Resultado:

b. Usando o Comparador Personalizado

Também podemos fornecer nosso próprio comparador personalizado para o método Sort (). Isso instruiria o compilador C # a usar o comparador personalizado em vez do padrão.

Para criar um comparador personalizado, precisamos implementar o método Compare () na interface IComparer. O código abaixo demonstra como criar um comparador que classifique os elementos em ordem decrescente.

Criamos uma classe, a herdamos da interface IComparer, implementamos o método Compare () e a substituímos para comparar os elementos em ordem decrescente.

Código:

using System;
public class DescendingComparer : System.Collections.IComparer
(
public int Compare(Object a, Object b)
(
return (new System.Collections.CaseInsensitiveComparer()).Compare(b, a);
)
)
public class Program
(
public static void Main()
(
String() strArray = ("I", "Am", "Learning", "Array", "Sorting", "In", "C#");
int() intArray = (23, 76, 12, 43, 90, 30);
Array.Sort(strArray, new DescendingComparer());
Array.Sort(intArray, new DescendingComparer());
Console.WriteLine("Sorted String Array in Descending Order:\n");
DisplayArray(strArray);
Console.WriteLine("\n\n\nSorted Integer Array in Desc Order:\n");
DisplayArray(intArray);
)
static void DisplayArray(string() arr)
(
foreach (string a in arr)
(
Console.Write(a + "\t");
)
)
static void DisplayArray(int() arr)
(
foreach (int a in arr)
(
Console.Write(a + "\t");
)
)
)

Resultado:

c. Usando pares de valor-chave

O C # também fornece uma maneira de classificar uma matriz usando valores-chave de outra matriz. O exemplo abaixo possui pares de valores-chave de nomes e sobrenomes de pessoas. Classificá-los por nome e sobrenome usando o método Sort ().

Código:

using System;
public class Program
(
public static void Main()
(
String() firstNames = ("Tom", "Jack", "Anna", "Veronica", "Jessica", "Mike");
String() lastNames = ("Phelps", "Anderson", "Spectre", "Clarke", "Williams", "Fonseca");
Array.Sort(firstNames, lastNames);
Console.WriteLine("Sorted by First Names:\n");
DisplayArray(firstNames, lastNames);
Array.Sort(lastNames, firstNames);
Console.WriteLine("\n\nSorted by Last Names:\n");
DisplayArray(firstNames, lastNames);
)
static void DisplayArray(string() arr1, string() arr2)
(
for (int i = 0; i < arr1.Length; i++)
(
Console.WriteLine(arr1(i) + " " + arr2(i));
)
)
)

Resultado:

2. Classificando uma lista em C #

Vejamos as diferentes maneiras pelas quais podemos classificar uma lista em C #.

Nota - Para usar Listas em C #, incluindo a biblioteca System.Collections.Generic.

uma. Usando o Comparador Padrão

Este é o método padrão sort (). se nenhum comparador for passado explicitamente para o método, o c # usará a ordem crescente para organizar os elementos.

Código:

public class Program
using System.Collections.Generic;
(
public static void Main()
(
String() strArray = ("I", "Am", "Learning", "Array", "Sorting", "In", "C#");
List strList = new List(strArray);
int() intArray = (23, 76, 12, 43, 90, 30);
List intList = new List(intArray);
strList.Sort();
intList.Sort();
Console.WriteLine("Sorted String List:\n");
DisplayList(strList);
Console.WriteLine("\n\n\nSorted Integer List:\n");
DisplayList(intList);
)
static void DisplayList(List myList)
(
foreach (string a in myList)
(
Console.Write(a + "\t");
)
)
static void DisplayList(List myList)
(
foreach (int a in myList)
(
Console.Write(a + "\t");
)
)
)

Resultado:

b. Usando o Comparador Personalizado

Também podemos fornecer nosso próprio comparador personalizado com o método sort (). Isso instruiria o compilador c # a usar o comparador personalizado em vez do padrão.

Para criar um comparador personalizado, precisamos implementar o método Compare () na interface IComparer. O código abaixo demonstra como criar um comparador que classifique os elementos em ordem decrescente.

Criamos uma classe, a herdamos da interface IComparer, implementamos o método Compare () e a substituímos para comparar os elementos em ordem decrescente.

Código:

using System;
using System.Collections.Generic;
public class LengthComparer : IComparer
(
public int Compare(string a, string b)
(
return (a.Length.CompareTo(b.Length));
)
)
public class DigitSumComparer : IComparer
(
public int Compare(int a, int b)
(
int sum_a = 0;
int sum_b = 0;
while (a > 0)
(
sum_a += (a % 10);
a /= 10;
)
while (b > 0)
(
sum_b += (b % 10);
b /= 10;
)
return (sum_a.CompareTo(sum_b));
)
)
public class Program
(
public static void Main()
(
LengthComparer lc = new LengthComparer();
DigitSumComparer dsc = new DigitSumComparer();
String() strArray = ("I", "Am", "Learning", "Array", "Sorting", "In", "C#");
List strList = new List(strArray);
int() intArray = (23, 76, 12, 43, 90, 30);
List intList = new List(intArray);
strList.Sort(lc);
intList.Sort(dsc);
Console.WriteLine("Sorted String List by Length:\n");
DisplayList(strList);
Console.WriteLine("\n\n\nSorted Integer List by Sum of Digits:\n");
DisplayList(intList);
)
static void DisplayList(List myList)
(
foreach (string a in myList)
(
Console.Write(a + "\t");
)
)
static void DisplayList(List myList)
(
foreach (int a in myList)
(
Console.Write(a + "\t");
)
)
)

Resultado:

Classificando tipos de lista complexos

Tipos de lista complexos são listas definidas pelo usuário. Para ser mais preciso, são listas de objetos de classes definidas pelo usuário. Sendo definidos pelo usuário, os objetos são uma mistura de vários tipos primitivos. É difícil classificar um tipo de lista complexo. O compilador C # espera que cada classe complexa seja herdada da interface IComparable e defina o método CompareTo (). Este método contém as instruções sobre como comparar os elementos da lista para classificação.

No exemplo abaixo, definimos uma classe de funcionários definida pelo usuário e classificamos os objetos Employee com base em seus IDs.

Exemplo 1

Código:

using System;
using System.Collections.Generic;
public class Employee : IComparable
(
public int id (get;set;)
public string name(get;set;)
public double salary(get;set;)
public int CompareTo(Employee e)
(
return this.id.CompareTo(e.id);
)
)
public class Program
(
public static void Main()
(
List emps = new List();
emps.Add(new Employee()
(id = 123, name = "Tom Phelps", salary = 20000.00));
emps.Add(new Employee()
(id = 897, name = "Jack Anderson", salary = 40050.50));
emps.Add(new Employee()
(id = 342, name = "Anna Spectre", salary = 31030.89));
emps.Add(new Employee()
(id = 219, name = "Veronica Clarke", salary = 66333.66));
emps.Add(new Employee()
(id = 642, name = "Jessica Williams", salary = 50505.05));
emps.Add(new Employee()
(id = 923, name = "Mike Fonseca", salary = 76543.21));
Console.WriteLine("Original Employee List:\n");
DisplayList(emps);
emps.Sort();
Console.WriteLine("\n\nSorted Employee List by IDs:\n");
DisplayList(emps);
)
static void DisplayList(List emp)
(
foreach (Employee e in emp)
(
Console.WriteLine("Id: " + e.id + ", Name: " + e.name + ", Salary: " + e.salary);
)
)
)

Resultado:

Agora, a pergunta óbvia que vem à mente é que, e se quisermos classificar os objetos da classe Employee com base em alguma outra propriedade? Isso é possível. Nós precisaríamos implementar a interface IComparer. Vamos dar uma olhada no exemplo abaixo para entender.

Exemplo 2

Código:

using System;
using System.Collections.Generic;
public class Employee
(
public int id (get;set;)
public string name(get;set;)
public double salary(get;set;)
)
public class SortByName : IComparer
(
public int Compare(Employee e1, Employee e2)
(
return e1.name.CompareTo(e2.name);
)
)
public class SortBySalary : IComparer
(
public int Compare(Employee e1, Employee e2)
(
return e1.salary.CompareTo(e2.salary);
)
)
public class Program
(
public static void Main()
(
SortByName sbn = new SortByName();
SortBySalary sbs = new SortBySalary();
List emps = new List();
emps.Add(new Employee()
(id = 123, name = "Tom Phelps", salary = 20000.00));
emps.Add(new Employee()
(id = 897, name = "Jack Anderson", salary = 40050.50));
emps.Add(new Employee()
(id = 342, name = "Anna Spectre", salary = 31030.89));
emps.Add(new Employee()
(id = 219, name = "Veronica Clarke", salary = 66333.66));
emps.Add(new Employee()
(id = 642, name = "Jessica Williams", salary = 50505.05));
emps.Add(new Employee()
(id = 923, name = "Mike Fonseca", salary = 76543.21));
emps.Sort(sbn);
Console.WriteLine("Sorted Employee List by Names:\n");
DisplayList(emps);
emps.Sort(sbs);
Console.WriteLine("\n\nSorted Employee List by Salaries:\n");
DisplayList(emps);
)
static void DisplayList(List emp)
(
foreach (Employee e in emp)
(
Console.WriteLine("Id: " + e.id + ", Name: " + e.name + ", Salary: " + e.salary);
)
)
)

Resultado:

Conclusão

Portanto, este artigo abordou detalhadamente como classificar coleções em C #. Nós nos concentramos principalmente em matrizes e listas, pois essas duas abrangem todos os tipos primitivos também. Depois que o conceito de Classificação em C # é muito bem compreendido, torna-se fácil implementar a classificação em outras coleções, como Enumerações, Dicionários etc. Depois de concluir este artigo, é recomendável explorar a documentação do MSDN para obter mais implementações de Classificação em C #.

Artigos recomendados

Este é um guia para classificação em c #. Aqui discutimos o desempenho da classificação, tipos de classificação, como matriz e lista, juntamente com os exemplos e a implementação do código. Você também pode consultar os seguintes artigos para saber mais -

  1. Objetos em c #
  2. Modificadores de acesso em c #
  3. Classificação da bolha em Java
  4. Ponteiros em c #
  5. Classificação em Python
  6. Matriz de seqüência de caracteres em JavaScript
  7. Exemplo comparável em Java | Interface de coleção em Java
  8. Matriz de seqüências de caracteres em C com funções
  9. Exemplos diferentes de coleções em c #