¿El algoritmo de clasificación utilizado por el método Array.Sort()
de .NET es un algoritmo stable?¿El algoritmo de clasificación utilizado por el método `Array.Sort()` de .NET es un algoritmo estable?
Respuesta
De MSDN:
Esta aplicación realiza una especie inestable; es decir, si dos elementos son iguales, es posible que su orden no se conserve. Por el contrario, un género estable conserva el orden de los elementos que son iguales.
El género utiliza una ordenación introspectiva. (Quicksort en la versión 4.0 y anterior del framework .NET).
Si necesita un tipo estable, puede usar Enumerable.OrderBy.
Solo tenga en cuenta que la respuesta sea real. El método de clasificación ha cambiado entre 4.5 y 4.0, de una clasificación rápida a una [clasificación introspectiva] (http://ru.wikipedia.org/wiki/Introsort). – Razoomnick
[Aquí] (https://en.wikipedia.org/wiki/Introsort) es el mismo artículo (tipo introspectivo) en inglés. – Xynariz
OrderBy no siempre es un sustituto adecuado, ya que devuelve una copia en lugar de ordenar en el lugar. –
No, isn't:
Este método utiliza el algoritmo QuickSort. Esta implementación realiza una clasificación inestable
Como han indicado otras respuestas, Array.Sort no es estable. Sin embargo, los métodos LINQ OrderBy (y OrderByDescending, etc.) son stable, que pueden ser muy útiles.
Agregando a Rasmus Faber's answer ...
selección LINQ, a través de Enumerable.OrderBy y Enumerable.ThenBy, es una aplicación ordenación estable, que puede ser utilizado como una alternativa a Array.Sort. De Enumerable.OrderBy documentation over at MSDN:
Este método realiza un tipo estable; es decir, si las claves de dos elementos son iguales, se conserva el orden de los elementos . Por el contrario, una ordenación inestable no conserva el orden de los elementos que tienen la misma clave.
También, cualquier aplicación tipo inestable, como la de Array.Sort
, se puede estabilizar mediante el uso de la posición de los elementos en la secuencia de origen o matriz como una tecla adicional para servir como un desempate. A continuación es un tal aplicación, como un método de extensión genérico en cualquier matriz unidimensional y que convierte Array.Sort
en una especie estable:
using System;
using System.Collections.Generic;
public static class ArrayExtensions {
public static void StableSort<T>(this T[] values, Comparison<T> comparison) {
var keys = new KeyValuePair<int, T>[values.Length];
for (var i = 0; i < values.Length; i++)
keys[i] = new KeyValuePair<int, T>(i, values[i]);
Array.Sort(keys, values, new StabilizingComparer<T>(comparison));
}
private sealed class StabilizingComparer<T> : IComparer<KeyValuePair<int, T>>
{
private readonly Comparison<T> _comparison;
public StabilizingComparer(Comparison<T> comparison) {
_comparison = comparison;
}
public int Compare(KeyValuePair<int, T> x,
KeyValuePair<int, T> y) {
var result = _comparison(x.Value, y.Value);
return result != 0 ? result : x.Key.CompareTo(y.Key);
}
}
}
continuación es un programa de muestra usando StableSort
desde arriba:
static class Program
{
static void Main()
{
var unsorted = new[] {
new Person { BirthYear = 1948, Name = "Cat Stevens" },
new Person { BirthYear = 1955, Name = "Kevin Costner" },
new Person { BirthYear = 1952, Name = "Vladimir Putin" },
new Person { BirthYear = 1955, Name = "Bill Gates" },
new Person { BirthYear = 1948, Name = "Kathy Bates" },
new Person { BirthYear = 1956, Name = "David Copperfield" },
new Person { BirthYear = 1948, Name = "Jean Reno" },
};
Array.ForEach(unsorted, Console.WriteLine);
Console.WriteLine();
var unstable = (Person[]) unsorted.Clone();
Array.Sort(unstable, (x, y) => x.BirthYear.CompareTo(y.BirthYear));
Array.ForEach(unstable, Console.WriteLine);
Console.WriteLine();
var stable = (Person[]) unsorted.Clone();
stable.StableSort((x, y) => x.BirthYear.CompareTo(y.BirthYear));
Array.ForEach(stable, Console.WriteLine);
}
}
sealed class Person
{
public int BirthYear { get; set; }
public string Name { get; set; }
public override string ToString() {
return string.Format(
"{{ BirthYear = {0}, Name = {1} }}",
BirthYear, Name);
}
}
a continuación se muestra la salida del programa de ejemplo anterior (que se ejecuta en una máquina con Windows Vista SP1 y .NET Framework 3.5 SP1 instalado):
{ BirthYear = 1948, Name = Cat Stevens }
{ BirthYear = 1955, Name = Kevin Costner }
{ BirthYear = 1952, Name = Vladimir Putin }
{ BirthYear = 1955, Name = Bill Gates }
{ BirthYear = 1948, Name = Kathy Bates }
{ BirthYear = 1956, Name = David Copperfield }
{ BirthYear = 1948, Name = Jean Reno }
{ BirthYear = 1948, Name = Jean Reno }
{ BirthYear = 1948, Name = Kathy Bates }
{ BirthYear = 1948, Name = Cat Stevens }
{ BirthYear = 1952, Name = Vladimir Putin }
{ BirthYear = 1955, Name = Bill Gates }
{ BirthYear = 1955, Name = Kevin Costner }
{ BirthYear = 1956, Name = David Copperfield }
{ BirthYear = 1948, Name = Cat Stevens }
{ BirthYear = 1948, Name = Kathy Bates }
{ BirthYear = 1948, Name = Jean Reno }
{ BirthYear = 1952, Name = Vladimir Putin }
{ BirthYear = 1955, Name = Kevin Costner }
{ BirthYear = 1955, Name = Bill Gates }
{ BirthYear = 1956, Name = David Copperfield }
ACTUALIZACIÓN: Este código no estabiliza la matriz.Ordenar (asegúrese de que los elementos se ordenan siempre en el mismo orden):
public static class ComparisonExtensions
{
public static Comparison<T> WithGetHashCode<T>(this Comparison<T> current)
{
return (x, y) =>
{
var result = current(x, y);
if (result == 0)
return x.GetHashCode() - y.GetHashCode();
return result;
};
}
}
Uso:
Comparison<Person> comparison = (x, y) => x.BirthYear.CompareTo(y.BirthYear);
Array.Sort(unstable, comparison.WithGetHashCode());
Es evidente que no entiende el significado de un tipo estable. No importa 'Comparación 'que use,' Array.Sort' es inestable. – leppie
Yo no lo creo. Está estabilizado por HashCode, en la medida en que los objetos tienen el mismo orden HashCode, es inestable (no significa que la referencia sea igual). Así que escribí que el aloritmo está estabilizado por HashCode, significa que, en la medida en que los objetos tienen un HashCode diferente, es estable. – halority
¿Y qué sucede cuando cambio 2 elementos "duplicados" antes de ordenar? ¿Esperas que el hashcode cambie repentinamente? – leppie
- 1. ¿Qué algoritmo de clasificación utiliza el método Array.Sort() de .NET?
- 2. ¿Qué algoritmo usa el método de clasificación de Ruby?
- 3. ¿Qué algoritmo de clasificación implementa .NET Framework?
- 4. Un algoritmo de clasificación
- 5. ¿Cuál es el mejor algoritmo de clasificación de asientos reservados?
- 6. ¿Qué algoritmo de clasificación utiliza LINQ "OrderBy"?
- 7. Array.sort Clasificación de la estabilidad en diferentes navegadores
- 8. Algoritmo Problema Clasificación
- 9. ¿Qué es una implementación de algoritmo de clasificación externa eficiente y estable (escrita en c)?
- 10. ¿Existe un algoritmo de "clasificación binaria"?
- 11. Clasificación estable, es decir, clasificación mínimamente disruptiva
- 12. Algoritmo genético: ¿qué es la selección de estado estable?
- 13. ¿Cuál es el beneficio de que un algoritmo de ordenamiento sea estable?
- 14. Algoritmo eficiente de clasificación de cadenas
- 15. algoritmo de STL más utilizado, predicados, iteradores
- 16. ¿Qué algoritmo de clasificación de múltiples criterios usar?
- 17. Elija el algoritmo de clasificación correcto. Lineal o no lineal?
- 18. Algoritmo de clasificación basado en comparación
- 19. ¿Cuáles son los criterios para elegir un algoritmo de clasificación?
- 20. ¿Qué algoritmo de criptografía .NET incorporado es el más seguro?
- 21. Algoritmo utilizado en Ruby para "String # include?"
- 22. Medición del rendimiento del algoritmo de clasificación
- 23. ¿Cuándo se usa cada algoritmo de clasificación?
- 24. ¿Alguien puede describir el algoritmo utilizado por el motor Voxlap de Ken Silverman?
- 25. ¿Cómo funciona el algoritmo de ordenación MapReduce?
- 26. ¿Qué algoritmo (s) de clasificación utiliza MySQL?
- 27. ¿Qué algoritmo de clasificación usa PHP?
- 28. ¿Por qué funciona el algoritmo de Dijkstra?
- 29. ¿Por qué es este un algoritmo codicioso?
- 30. ¿Qué algoritmo de clasificación está detrás de un NSSortDescriptor?
Cuando hace la diferencia entre ordenación estable y la materia especie inestable? Soy curioso. – tuinstoel
@tuinstoel - Cuando desee preservar el orden inicial de los elementos. Supongamos que tiene una lista de productos que ya está clasificada según algunos criterios (IE alfabéticamente), si ordena por categoría usando un criterio estable, los criterios de clasificación originales se conservan dentro de los grupos de productos que son de la misma categoría, los productos ahora se ordenarán por categoría y alfabéticamente. –
Esto es omisión evidente. [C++] (http://www.cplusplus.com/reference/algorithm/stable_sort/), [Golang] (https://golang.org/pkg/sort/#Stable) y [Python] (https: // docs.python.org/3/library/stdtypes.html#list.sort) ofrecen funciones de clasificación in situ estables. –