qsort
sort
da biblioteca de arrays de JavaEstratégia "divide and conquer":
Caso base: se a sequência tem 0 ou 1 valores não há nada a fazer (já está ordenada).
Começamos com a sequência: \[ \begin{array}{|c|c|c|c|c|c|c|c|} \hline 55 & 41 & 59 & 26 & 53 & 58 & 97 & 93 \\ \hline \end{array} \]
Escolhemos o primeiro valor como pivot e re-organizamos os valores: \[ \underbrace{\begin{array}{|c|c|c|} \hline 41 & 26 & 53 \\ \hline \end{array}}_{<55} \begin{array}{|c|} \hline \textbf{55} \\ \hline \end{array} \underbrace{\begin{array}{|c|c|c|c|} \hline 59 & 58 & 97 & 93 \\ \hline \end{array}}_{\geq55} \]
Recursivamente ordenamos as duas sub-sequências repetindo este método: \[ \begin{array}{ccc} \begin{array}{|c|c|c|} \hline 41 & 26 & 53 \\ \hline \end{array} & \begin{array}{|c|} \hline 55 \\ \hline \end{array} & \begin{array}{|c|c|c|c|} \hline 59 & 58 & 97 & 93 \\ \hline \end{array} \\ \overset{\vdots}{\downarrow} & & \overset{\vdots}{\downarrow} \\ \begin{array}{|c|c|c|} \hline 26 & 41 & 53 \\ \hline \end{array} & & \begin{array}{|c|c|c|c|} \hline 58 & 59 & 93 & 97 \\ \hline \end{array} \end{array} \]
Sequência final ordenada: \[ \begin{array}{|c|c|c|c|c|c|c|c|} \hline 26 & 41 & 53 & 55 & 58 & 93 & 97 \\ \hline \end{array} \]
\[ \begin{array}{l} \text{Dados:}\quad v[0], v[1], \ldots, v[n-1] \\[1ex] \textsf{qsort}(l, u): \quad \color{red}{\text{// ordenar}~v[l\ldots u]} \\ \qquad \text{se}~ l\geq u~\text{então termina imediatamente;} \\ \qquad \color{red}{\text{// caso contrário:}} \\ \qquad m \gets \textsf{partition}(l, u)~ \color{red}{\text{// partir usando pivot}}\\ \qquad \textsf{qsort}(l, m-1) ~ \color{red}{\text{// ordenar}~v[l\ldots m-1]}\\ \qquad \textsf{qsort}(m+1, u) ~ \color{red}{\text{// ordenar}~v[m+1\ldots u]} \end{array} \]
\[ \begin{array}{|c|ccc|ccc|ccc|} \hline \textit{pivot} & & <\textit{pivot} & & & \geq \textit{pivot} & & & ? & \\ \hline \overset{\uparrow}{l} & \overset{\uparrow}{l+1} & & \overset{\uparrow}{m} & & & & \overset{\uparrow}{i} & & \overset{\uparrow}{u} \end{array} \]
\[ \begin{array}{|ccc|c|ccc|} \hline & <\textit{pivot} & & \textit{pivot} & & \geq \textit{pivot} & \\ \hline \overset{\uparrow}{l} & & \overset{\uparrow}{m-1} & \overset{\uparrow}{m} & \overset{\uparrow}{m+1} & & \overset{\uparrow}{u} \end{array} \]
\[ \begin{array}{l} \textsf{partition}(l,u):\\ \qquad m \gets l\\ \qquad \textsf{para} ~i~\text{de} ~l+1 ~\text{até}~u: \\ \qquad\quad \text{se}~ v[i] < v[l]: \\ \qquad\quad\quad\quad m \gets m+1\\ \qquad\quad\quad\quad \text{trocar}~ v[i], v[m]\\ \qquad \text{trocar}~ v[l], v[m]\\ \qquad \text{retornar}~m \end{array} \]
void quicksort_rec(int vec[], int l, int u) {
int m;
if(l >= u)
return; // caso base; termina logo
// senão: caso recursivo
m = partition(vec, l, u);
// partir usando pivot
quicksort_rec(vec, l, m-1);
// ordenar vec[l..m-1]
quicksort_rec(vec, m+1, u);
// ordenar vec[m+1..u]
}
int partition(int vec[], int l, int u) {
int i, m, temp;
m = l; // m: indice do ponto médio
for(i = l+1; i<=u; i++) {
if(vec[i] < vec[l]) { // fora de ordem
m ++;
temp = vec[i]; // trocar vec[i], vec[m]
vec[i] = vec[m];
vec[m] = temp;
}
}
temp = vec[l]; // trocar vec[l], vec[m]
vec[l] = vec[m];
vec[m] = temp;
return m;
}
\[ \begin{array}{|ccc|c|ccc|} \hline & <\textit{pivot} & & \textit{pivot} & & \geq \textit{pivot} & \\ \hline \overset{\uparrow}{l} & & \overset{\uparrow}{m-1} & \overset{\uparrow}{m} & \overset{\uparrow}{m+1} & & \overset{\uparrow}{u} \end{array} \]
\[ \begin{array}{r} \begin{array}{|c|c|c|c|c|c|c|c|} \hline 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 \\ \hline \end{array} \\ \hfill \downarrow\hfill \\ \begin{array}{|c|} \hline \textbf{1} \\ \hline \end{array} \begin{array}{|c|c|c|c|c|c|c|} \hline 2 & 3 & 4 & 5 & 6 & 7 & 8 \\ \hline \end{array} \\ \hfill \downarrow\hfill \\ \begin{array}{|c|} \hline \textbf{2} \\ \hline \end{array} \begin{array}{|c|c|c|c|c|c|} \hline 3 & 4 & 5 & 6 & 7 & 8 \\ \hline \end{array} \\ \hfill \overset{\downarrow }{\vdots}\hfill \end{array} \]
Tempos para ordenação de \(n\) valores aleatórios (segundos):
\(n\) | seleção | inserção | quicksort |
---|---|---|---|
10000 | 0.142152 | 0.082719 | 0.001343 |
20000 | 0.578847 | 0.336311 | 0.002831 |
40000 | 2.279674 | 1.349157 | 0.005698 |