Como o sort () do Javascript funciona?

91

Como o código a seguir classifica essa matriz em ordem numérica?

var array=[25, 8, 7, 41]

array.sort(function(a,b){
  return a - b
})

Eu sei que se o resultado do cálculo for ...

Menor que 0 : "a" é classificado para ter um índice menor que "b".
Zero: "a" e "b" são considerados iguais e nenhuma classificação é executada.
Maior que 0: "b" é classificado para ser um índice menor que "a".

A função de retorno de chamada de classificação de matriz é chamada muitas vezes durante o curso da classificação?

Nesse caso, gostaria de saber quais dois números são passados ​​para a função a cada vez. Presumi que primeiro levava "25" (a) e "8" (b), seguido por "7" (a) e "41" (b), então:

25 (a) - 8 (b) = 17 (maior que zero, então classifique "b" para ser um índice menor que "a"): 8, 25

7 (a) - 41 (b) = -34 (menor que zero, então classifique "a" para ser um índice menor que "b": 7, 41

Como os dois conjuntos de números são classificados em relação um ao outro?

Por favor, ajude um novato com dificuldades!

cw84
fonte
5
Espero que isso faça algum sentido distorcido!
cw84

Respostas:

51

A função de retorno de chamada de classificação de matriz é chamada muitas vezes durante o curso da classificação?

sim

Se sim, gostaria de saber quais dois números são passados ​​para a função a cada vez

Você pode descobrir a si mesmo com:

array.sort((a,b) => {
  console.log(`comparing ${a},${b}`);
  return a > b ? 1
               : a === b ? 0 
                         : -1;
});

EDITAR

Esta é a saída que obtive:

25,8
25,7
8,7
25,41
OscarRyz
fonte
8
em vez disso, faça um console.log para firebug ou html do elemento DIV .innerHTML + = "comparing" + a + "," + b + "\ n";
Joshua
2
Lembre-se que este é um site semelhante a um wiki e podemos editar outras respostas para torná-las melhores :)
Pablo Fernandez
6
Apenas uma observação para a nova sintaxe ES6: array.sort((a,b) => a - b);é uma sintaxe válida
Sterling Archer
1
se a função de classificação retornar -ve então ela troca e + ve então ela não troca ??
Mahi
2
@ShekharReddy você ainda pode usar operadores para comparar. Eu atualizei a resposta.
OscarRyz
44

O interpretador de JavaScript tem algum tipo de algoritmo de classificação implementação de embutido nele. Ele chama a função de comparação algumas vezes durante a operação de classificação. O número de vezes que a função de comparação é chamada depende do algoritmo específico, dos dados a serem classificados e da ordem em que estão antes da classificação.

Alguns algoritmos de classificação funcionam mal em listas já classificadas porque faz com que façam muito mais comparações do que no caso típico. Outros lidam bem com listas pré-classificadas, mas têm outros casos em que podem ser "enganados" para ter um desempenho insatisfatório.

Existem muitos algoritmos de classificação em uso comum porque nenhum algoritmo único é perfeito para todos os propósitos. Os dois mais usados ​​para classificação genérica são Quicksort e classificação por mesclagem . O Quicksort geralmente é o mais rápido dos dois, mas a classificação por mesclagem tem algumas propriedades interessantes que podem torná-lo uma escolha geral melhor. A classificação de mesclagem é estável , enquanto o Quicksort não. Ambos os algoritmos são paralelizáveis, mas a maneira como a ordenação por mesclagem funciona torna uma implementação paralela mais eficiente, todo o resto sendo igual.

Seu interpretador JavaScript particular pode usar um desses algoritmos ou algo totalmente diferente. O padrão ECMAScript não especifica qual algoritmo uma implementação conforme deve usar. Até rejeita explicitamente a necessidade de estabilidade.

Warren Young
fonte
1
FWIW, Quicksort básico é um dos algoritmos que pode ser "enganado" para ter um desempenho insatisfatório. Na forma simples, ele tem desempenho O (N ^ 2) para listas que já estão classificadas ou exatamente invertidas. A maioria dos algoritmos de biblioteca Quicksort tem um número de otimizações não óbvias que ajudam a evitar esses cenários comuns de pior caso.
Adisak,
3
JavaScriptCore realmente usa uma árvore AVL para classificação, pois é necessário se comportar de forma determinística em face das funções de comparação que modificam a matriz que está sendo classificada.
olliej
11

Pares de valores são comparados, um par de cada vez. Os pares que são comparados são um detalhe de implementação - não presuma que serão iguais em todos os navegadores. O retorno de chamada pode ser qualquer coisa (portanto, você pode classificar strings ou algarismos romanos ou qualquer outra coisa em que possa criar uma função que retorne 1,0, -1).

Uma coisa a ter em mente com a classificação do JavaScript é que não é garantido que seja estável.

Nosredna
fonte
5

A função de retorno de chamada de classificação de matriz é chamada muitas vezes durante o curso da classificação?

Sim, é exatamente isso. O retorno de chamada é usado para comparar pares de elementos na matriz conforme necessário para determinar em que ordem eles devem estar. Essa implementação da função de comparação não é atípica ao lidar com uma classificação numérica. Detalhes nas especificações ou em alguns outros sites mais legíveis .

TJ Crowder
fonte
4

A função de retorno de chamada de classificação de matriz é chamada muitas vezes durante o curso da classificação?

Como esta é uma classificação por comparação, dados N itens, a função de retorno de chamada deve ser chamada em média (N * Lg N) vezes para uma classificação rápida como Quicksort . Se o algoritmo usado for algo como Bubble Sort , a função de retorno de chamada será invocada em média (N * N) vezes.

O número mínimo de invocações para uma classificação por comparação é (N-1) e isso serve apenas para detectar uma lista já classificada (ou seja, no início do Bubble Sort se nenhuma troca ocorrer).

Adisak
fonte
2

Conhecimento Profundo

Se o resultado for negativo, a é classificado antes de b.

Se o resultado for positivo, b é classificado antes de a.

Se o resultado for 0, nenhuma alteração será feita na ordem de classificação dos dois valores.

NOTA:

Este código é a visão dentro do método de classificação passo a passo.

RESULTADO:

let arr = [90, 1, 20, 14, 3, 55];
var sortRes = [];
var copy = arr.slice();		//create duplicate array
var inc = 0;	//inc meant increment
copy.sort((a, b) => {
	sortRes[inc] = [ a, b, a-b ];
	inc += 1;
	return a - b;
});
var p = 0;
for (var i = 0; i < inc; i++) {
	copy = arr.slice();
	copy.sort((a, b) => {
		p += 1;
		if (p <= i ) {
			return a - b;
		}
		else{
			return false;
		}
	});
	p = 0;
	console.log(copy +' \t a: '+ sortRes[i][0] +' \tb: '+ sortRes[i][1] +'\tTotal: '+ sortRes[i][2]);
}

Aman Silawat
fonte
0

execute este código. Você pode ver o processo de classificação exato, passo a passo, do início ao fim.

var array=[25, 8, 7, 41]
var count = 1;
array.sort( (a,b) => { 
console.log(`${count++}). a: ${a} | b: ${b}`);
return a-b;
});
console.log(array);
Tinu Mathai
fonte
copiado e colado no console e ele apenas retornou indefinido.
iPzard de
-2
var array=[25, 8, 7, 41]

array.sort(function(a,b){
  console.log(`a = ${a} , b = ${b}`);
  return a - b
});

RESULTADO

  • a = 8, b = 25
  • a = 7, b = 8
  • a = 41, b = 7
  • a = 41, b = 8
  • a = 41, b = 25

no meu navegador (Google Chrome versão 70.0.3538.77 (versão oficial) (64 bits)) na primeira iteração, o argumento a é o segundo elemento em uma matriz e o argumento b é o primeiro elemento de uma matriz.

se a função Compare retornar

  1. Valor negativo que b é movido para a.
  2. Valor positivo que a é movido para b.
  3. 0 (zero) ambos a & b permanecerão como estão.
Harshaan Nihal khan
fonte