A continuación se muestra una implementación recursiva típica de Quick Sort que usa el último elemento como pivote.
C++
// CPP code for recursive function of Quicksort #include <bits/stdc++.h> using namespace std; // Function to swap numbers void swap(int* a, int* b) { int temp = *a; *a = *b; *b = temp; } /* This function takes last element as pivot, places the pivot element at its correct position in sorted array, and places all smaller (smaller than pivot) to left of pivot and all greater elements to right of pivot */ int partition(int arr[], int l, int h) { int x = arr[h]; int i = (l - 1); for (int j = l; j <= h - 1; j++) { if (arr[j] <= x) { i++; swap(&arr[i], &arr[j]); } } swap(&arr[i + 1], &arr[h]); return (i + 1); } /* A[] --> Array to be sorted, l --> Starting index, h --> Ending index */ void quickSort(int A[], int l, int h) { if (l < h) { /* Partitioning index */ int p = partition(A, l, h); quickSort(A, l, p - 1); quickSort(A, p + 1, h); } } // Driver code int main() { int n = 5; int arr[n] = { 4, 2, 6, 9, 2 }; quickSort(arr, 0, n - 1); for (int i = 0; i < n; i++) { cout << arr[i] << " "; } return 0; }
Java
// Java program for implementation of QuickSort import java.util.*; class QuickSort { /* This function takes last element as pivot, places the pivot element at its correct position in sorted array, and places all smaller (smaller than pivot) to left of pivot and all greater elements to right of pivot */ static int partition(int arr[], int low, int high) { int pivot = arr[high]; int i = (low - 1); // index of smaller element for (int j = low; j <= high - 1; j++) { // If current element is smaller than or // equal to pivot if (arr[j] <= pivot) { i++; // swap arr[i] and arr[j] int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } } // swap arr[i+1] and arr[high] (or pivot) int temp = arr[i + 1]; arr[i + 1] = arr[high]; arr[high] = temp; return i + 1; } /* The main function that implements QuickSort() arr[] --> Array to be sorted, low --> Starting index, high --> Ending index */ static void qSort(int arr[], int low, int high) { if (low < high) { /* pi is partitioning index, arr[pi] is now at right place */ int pi = partition(arr, low, high); // Recursively sort elements before // partition and after partition qSort(arr, low, pi - 1); qSort(arr, pi + 1, high); } } // Driver code public static void main(String args[]) { int n = 5; int arr[] = { 4, 2, 6, 9, 2 }; qSort(arr, 0, n - 1); for (int i = 0; i < n; i++) { System.out.print(arr[i] + " "); } } }
Python3
# A typical recursive Python # implementation of QuickSort # Function takes last element as pivot, # places the pivot element at its correct # position in sorted array, and places all # smaller (smaller than pivot) to left of # pivot and all greater elements to right # of pivot def partition(arr, low, high): i = (low - 1) # index of smaller element pivot = arr[high] # pivot for j in range(low, high): # If current element is smaller # than or equal to pivot if arr[j] <= pivot: # increment index of # smaller element i += 1 arr[i], arr[j] = arr[j], arr[i] arr[i + 1], arr[high] = arr[high], arr[i + 1] return (i + 1) # The main function that implements QuickSort # arr[] --> Array to be sorted, # low --> Starting index, # high --> Ending index # Function to do Quick sort def quickSort(arr, low, high): if low < high: # pi is partitioning index, arr[p] is now # at right place pi = partition(arr, low, high) # Separately sort elements before # partition and after partition quickSort(arr, low, pi-1) quickSort(arr, pi + 1, high) # Driver Code if __name__ == '__main__' : arr = [4, 2, 6, 9, 2] n = len(arr) # Calling quickSort function quickSort(arr, 0, n - 1) for i in range(n): print(arr[i], end = " ")
C#
// C# program for implementation of // QuickSort using System; class GFG { /* This function takes last element as pivot, places the pivot element at its correct position in sorted array, and places all smaller (smaller than pivot) to left of pivot and all greater elements to right of pivot */ static int partition(int[] arr, int low, int high) { int temp; int pivot = arr[high]; // index of smaller element int i = (low - 1); for (int j = low; j <= high - 1; j++) { // If current element is // smaller than or // equal to pivot if (arr[j] <= pivot) { i++; // swap arr[i] and arr[j] temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } } // swap arr[i+1] and arr[high] // (or pivot) temp = arr[i + 1]; arr[i + 1] = arr[high]; arr[high] = temp; return i + 1; } /* The main function that implements QuickSort() arr[] --> Array to be sorted, low --> Starting index, high --> Ending index */ static void qSort(int[] arr, int low, int high) { if (low < high) { /* pi is partitioning index, arr[pi] is now at right place */ int pi = partition(arr, low, high); // Recursively sort elements // before partition and after // partition qSort(arr, low, pi - 1); qSort(arr, pi + 1, high); } } // Driver code public static void Main() { int n = 5; int[] arr = { 4, 2, 6, 9, 2 }; qSort(arr, 0, n - 1); for (int i = 0; i < n; i++) Console.Write(arr[i] + " "); } } // This code is contributed by nitin mittal.
PHP
<?php // PHP code for recursive function // of Quicksort // Function to swap numbers function swap(&$a, &$b) { $temp = $a; $a = $b; $b = $temp; } /* This function takes last element as pivot, places the pivot element at its correct position in sorted array, and places all smaller (smaller than pivot) to left of pivot and all greater elements to right of pivot */ function partition (&$arr, $l, $h) { $x = $arr[$h]; $i = ($l - 1); for ($j = $l; $j <= $h - 1; $j++) { if ($arr[$j] <= $x) { $i++; swap ($arr[$i], $arr[$j]); } } swap ($arr[$i + 1], $arr[$h]); return ($i + 1); } /* A[] --> Array to be sorted, l --> Starting index, h --> Ending index */ function quickSort(&$A, $l, $h) { if ($l < $h) { /* Partitioning index */ $p = partition($A, $l, $h); quickSort($A, $l, $p - 1); quickSort($A, $p + 1, $h); } } // Driver code $n = 5; $arr = array(4, 2, 6, 9, 2); quickSort($arr, 0, $n - 1); for($i = 0; $i < $n; $i++) { echo $arr[$i] . " "; } // This code is contributed by // rathbhupendra ?>
Javascript
<script> // JavaScript program for implementation of QuickSort /* This function takes last element as pivot, places the pivot element at its correct position in sorted array, and places all smaller (smaller than pivot) to left of pivot and all greater elements to right of pivot */ function partition(arr, low, high) { let temp; let pivot = arr[high]; // index of smaller element let i = (low - 1); for (let j = low; j <= high - 1; j++) { // If current element is // smaller than or // equal to pivot if (arr[j] <= pivot) { i++; // swap arr[i] and arr[j] temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } } // swap arr[i+1] and arr[high] // (or pivot) temp = arr[i + 1]; arr[i + 1] = arr[high]; arr[high] = temp; return i + 1; } /* The main function that implements QuickSort() arr[] --> Array to be sorted, low --> Starting index, high --> Ending index */ function qSort(arr, low, high) { if (low < high) { /* pi is partitioning index, arr[pi] is now at right place */ let pi = partition(arr, low, high); // Recursively sort elements // before partition and after // partition qSort(arr, low, pi - 1); qSort(arr, pi + 1, high); } } let n = 5; let arr = [ 4, 2, 6, 9, 2 ]; qSort(arr, 0, n - 1); for (let i = 0; i < n; i++) document.write(arr[i] + " "); </script>
Producción:
2 2 4 6 9
La implementación anterior se puede optimizar de muchas maneras
1) La implementación anterior utiliza el último índice como pivote. Esto provoca el peor de los casos en arrays ya ordenadas, que es un caso común. El problema se puede resolver eligiendo un índice aleatorio para el pivote o eligiendo el índice medio de la partición o eligiendo la mediana del primer, medio y último elemento de la partición para el pivote. (Vea esto para más detalles)
2) Para reducir la profundidad de recurrencia, recurra primero para la mitad más pequeña de la array y use una llamada de cola para recurrir a la otra.
3) La ordenación por inserción funciona mejor para pequeños subarreglos. La ordenación por inserción se puede usar para invocaciones en arreglos tan pequeños (es decir, donde la longitud es menor que un umbral t determinado experimentalmente). Por ejemplo,esta implementación de biblioteca de Quicksort usa la ordenación por inserción por debajo del tamaño 7.
A pesar de las optimizaciones anteriores, la función sigue siendo recursiva y usa la pila de llamadas de función para almacenar valores intermedios de l y h. La pila de llamadas de función almacena otra información de contabilidad junto con parámetros. Además, las llamadas a funciones implican gastos generales como almacenar registros de activación de la función que llama y luego reanudar la ejecución.
La función anterior se puede convertir fácilmente a una versión iterativa con la ayuda de una pila auxiliar. A continuación se muestra una implementación iterativa del código recursivo anterior.
C++
// An iterative implementation of quick sort #include <bits/stdc++.h> using namespace std; // A utility function to swap two elements void swap(int* a, int* b) { int t = *a; *a = *b; *b = t; } /* This function is same in both iterative and recursive*/ int partition(int arr[], int l, int h) { int x = arr[h]; int i = (l - 1); for (int j = l; j <= h - 1; j++) { if (arr[j] <= x) { i++; swap(&arr[i], &arr[j]); } } swap(&arr[i + 1], &arr[h]); return (i + 1); } /* A[] --> Array to be sorted, l --> Starting index, h --> Ending index */ void quickSortIterative(int arr[], int l, int h) { // Create an auxiliary stack int stack[h - l + 1]; // initialize top of stack int top = -1; // push initial values of l and h to stack stack[++top] = l; stack[++top] = h; // Keep popping from stack while is not empty while (top >= 0) { // Pop h and l h = stack[top--]; l = stack[top--]; // Set pivot element at its correct position // in sorted array int p = partition(arr, l, h); // If there are elements on left side of pivot, // then push left side to stack if (p - 1 > l) { stack[++top] = l; stack[++top] = p - 1; } // If there are elements on right side of pivot, // then push right side to stack if (p + 1 < h) { stack[++top] = p + 1; stack[++top] = h; } } } // A utility function to print contents of arr void printArr(int arr[], int n) { int i; for (i = 0; i < n; ++i) cout << arr[i] << " "; } // Driver code int main() { int arr[] = { 4, 3, 5, 2, 1, 3, 2, 3 }; int n = sizeof(arr) / sizeof(*arr); quickSortIterative(arr, 0, n - 1); printArr(arr, n); return 0; } // This is code is contributed by rathbhupendra
C
// An iterative implementation of quick sort #include <stdio.h> // A utility function to swap two elements void swap(int* a, int* b) { int t = *a; *a = *b; *b = t; } /* This function is same in both iterative and recursive*/ int partition(int arr[], int l, int h) { int x = arr[h]; int i = (l - 1); for (int j = l; j <= h - 1; j++) { if (arr[j] <= x) { i++; swap(&arr[i], &arr[j]); } } swap(&arr[i + 1], &arr[h]); return (i + 1); } /* A[] --> Array to be sorted, l --> Starting index, h --> Ending index */ void quickSortIterative(int arr[], int l, int h) { // Create an auxiliary stack int stack[h - l + 1]; // initialize top of stack int top = -1; // push initial values of l and h to stack stack[++top] = l; stack[++top] = h; // Keep popping from stack while is not empty while (top >= 0) { // Pop h and l h = stack[top--]; l = stack[top--]; // Set pivot element at its correct position // in sorted array int p = partition(arr, l, h); // If there are elements on left side of pivot, // then push left side to stack if (p - 1 > l) { stack[++top] = l; stack[++top] = p - 1; } // If there are elements on right side of pivot, // then push right side to stack if (p + 1 < h) { stack[++top] = p + 1; stack[++top] = h; } } } // A utility function to print contents of arr void printArr(int arr[], int n) { int i; for (i = 0; i < n; ++i) printf("%d ", arr[i]); } // Driver program to test above functions int main() { int arr[] = { 4, 3, 5, 2, 1, 3, 2, 3 }; int n = sizeof(arr) / sizeof(*arr); quickSortIterative(arr, 0, n - 1); printArr(arr, n); return 0; }
Java
// Java program for implementation of QuickSort import java.util.*; class QuickSort { /* This function takes last element as pivot, places the pivot element at its correct position in sorted array, and places all smaller (smaller than pivot) to left of pivot and all greater elements to right of pivot */ static int partition(int arr[], int low, int high) { int pivot = arr[high]; // index of smaller element int i = (low - 1); for (int j = low; j <= high - 1; j++) { // If current element is smaller than or // equal to pivot if (arr[j] <= pivot) { i++; // swap arr[i] and arr[j] int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } } // swap arr[i+1] and arr[high] (or pivot) int temp = arr[i + 1]; arr[i + 1] = arr[high]; arr[high] = temp; return i + 1; } /* A[] --> Array to be sorted, l --> Starting index, h --> Ending index */ static void quickSortIterative(int arr[], int l, int h) { // Create an auxiliary stack int[] stack = new int[h - l + 1]; // initialize top of stack int top = -1; // push initial values of l and h to stack stack[++top] = l; stack[++top] = h; // Keep popping from stack while is not empty while (top >= 0) { // Pop h and l h = stack[top--]; l = stack[top--]; // Set pivot element at its correct position // in sorted array int p = partition(arr, l, h); // If there are elements on left side of pivot, // then push left side to stack if (p - 1 > l) { stack[++top] = l; stack[++top] = p - 1; } // If there are elements on right side of pivot, // then push right side to stack if (p + 1 < h) { stack[++top] = p + 1; stack[++top] = h; } } } // Driver code public static void main(String args[]) { int arr[] = { 4, 3, 5, 2, 1, 3, 2, 3 }; int n = 8; // Function calling quickSortIterative(arr, 0, n - 1); for (int i = 0; i < n; i++) { System.out.print(arr[i] + " "); } } }
Python
# Python program for implementation of Quicksort # This function is same in both iterative and recursive def partition(arr, l, h): i = ( l - 1 ) x = arr[h] for j in range(l, h): if arr[j] <= x: # increment index of smaller element i = i + 1 arr[i], arr[j] = arr[j], arr[i] arr[i + 1], arr[h] = arr[h], arr[i + 1] return (i + 1) # Function to do Quick sort # arr[] --> Array to be sorted, # l --> Starting index, # h --> Ending index def quickSortIterative(arr, l, h): # Create an auxiliary stack size = h - l + 1 stack = [0] * (size) # initialize top of stack top = -1 # push initial values of l and h to stack top = top + 1 stack[top] = l top = top + 1 stack[top] = h # Keep popping from stack while is not empty while top >= 0: # Pop h and l h = stack[top] top = top - 1 l = stack[top] top = top - 1 # Set pivot element at its correct position in # sorted array p = partition( arr, l, h ) # If there are elements on left side of pivot, # then push left side to stack if p-1 > l: top = top + 1 stack[top] = l top = top + 1 stack[top] = p - 1 # If there are elements on right side of pivot, # then push right side to stack if p + 1 < h: top = top + 1 stack[top] = p + 1 top = top + 1 stack[top] = h # Driver code to test above arr = [4, 3, 5, 2, 1, 3, 2, 3] n = len(arr) quickSortIterative(arr, 0, n-1) print ("Sorted array is:") for i in range(n): print ("% d" % arr[i]), # This code is contributed by Mohit Kumra
C#
// C# program for implementation of QuickSort using System; class GFG { /* This function takes last element as pivot, places the pivot element at its correct position in sorted array, and places all smaller (smaller than pivot) to left of pivot and all greater elements to right of pivot */ static int partition(int[] arr, int low, int high) { int temp; int pivot = arr[high]; // index of smaller element int i = (low - 1); for (int j = low; j <= high - 1; j++) { // If current element is smaller // than or equal to pivot if (arr[j] <= pivot) { i++; // swap arr[i] and arr[j] temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } } // swap arr[i+1] and arr[high] // (or pivot) temp = arr[i + 1]; arr[i + 1] = arr[high]; arr[high] = temp; return i + 1; } /* A[] --> Array to be sorted, l --> Starting index, h --> Ending index */ static void quickSortIterative(int[] arr, int l, int h) { // Create an auxiliary stack int[] stack = new int[h - l + 1]; // initialize top of stack int top = -1; // push initial values of l and h to // stack stack[++top] = l; stack[++top] = h; // Keep popping from stack while // is not empty while (top >= 0) { // Pop h and l h = stack[top--]; l = stack[top--]; // Set pivot element at its // correct position in // sorted array int p = partition(arr, l, h); // If there are elements on // left side of pivot, then // push left side to stack if (p - 1 > l) { stack[++top] = l; stack[++top] = p - 1; } // If there are elements on // right side of pivot, then // push right side to stack if (p + 1 < h) { stack[++top] = p + 1; stack[++top] = h; } } } // Driver code public static void Main() { int[] arr = { 4, 3, 5, 2, 1, 3, 2, 3 }; int n = 8; // Function calling quickSortIterative(arr, 0, n - 1); for (int i = 0; i < n; i++) Console.Write(arr[i] + " "); } } // This code is contributed by anuj_67.
PHP
<?php // An iterative implementation of quick sort // A utility function to swap two elements function swap ( &$a, &$b ) { $t = $a; $a = $b; $b = $t; } /* This function is same in both iterative and recursive*/ function partition (&$arr, $l, $h) { $x = $arr[$h]; $i = ($l - 1); for ($j = $l; $j <= $h- 1; $j++) { if ($arr[$j] <= $x) { $i++; swap ($arr[$i], $arr[$j]); } } swap ($arr[$i + 1], $arr[$h]); return ($i + 1); } /* A[] --> Array to be sorted, l --> Starting index, h --> Ending index */ function quickSortIterative (&$arr, $l, $h) { // Create an auxiliary stack $stack=array_fill(0, $h - $l + 1, 0); // initialize top of stack $top = -1; // push initial values of l and h to stack $stack[ ++$top ] = $l; $stack[ ++$top ] = $h; // Keep popping from stack while is not empty while ( $top >= 0 ) { // Pop h and l $h = $stack[ $top-- ]; $l = $stack[ $top-- ]; // Set pivot element at its correct position // in sorted array $p = partition( $arr, $l, $h ); // If there are elements on left side of pivot, // then push left side to stack if ( $p-1 > $l ) { $stack[ ++$top ] = $l; $stack[ ++$top ] = $p - 1; } // If there are elements on right side of pivot, // then push right side to stack if ( $p+1 < $h ) { $stack[ ++$top ] = $p + 1; $stack[ ++$top ] = $h; } } } // A utility function to print contents of arr function printArr( $arr, $n ) { for ( $i = 0; $i < $n; ++$i ) echo $arr[$i]." "; } // Driver code $arr = array(4, 3, 5, 2, 1, 3, 2, 3); $n = count($arr); quickSortIterative($arr, 0, $n - 1 ); printArr($arr, $n ); // This is code is contributed by chandan_jnu ?>
Javascript
<script> // Javascript program for implementation of QuickSort /* This function takes last element as pivot, places the pivot element at its correct position in sorted array, and places all smaller (smaller than pivot) to left of pivot and all greater elements to right of pivot */ function partition(arr, low, high) { let temp; let pivot = arr[high]; // index of smaller element let i = (low - 1); for (let j = low; j <= high - 1; j++) { // If current element is smaller // than or equal to pivot if (arr[j] <= pivot) { i++; // swap arr[i] and arr[j] temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } } // swap arr[i+1] and arr[high] // (or pivot) temp = arr[i + 1]; arr[i + 1] = arr[high]; arr[high] = temp; return i + 1; } /* A[] --> Array to be sorted, l --> Starting index, h --> Ending index */ function quickSortIterative(arr, l, h) { // Create an auxiliary stack let stack = new Array(h - l + 1); stack.fill(0); // initialize top of stack let top = -1; // push initial values of l and h to // stack stack[++top] = l; stack[++top] = h; // Keep popping from stack while // is not empty while (top >= 0) { // Pop h and l h = stack[top--]; l = stack[top--]; // Set pivot element at its // correct position in // sorted array let p = partition(arr, l, h); // If there are elements on // left side of pivot, then // push left side to stack if (p - 1 > l) { stack[++top] = l; stack[++top] = p - 1; } // If there are elements on // right side of pivot, then // push right side to stack if (p + 1 < h) { stack[++top] = p + 1; stack[++top] = h; } } } let arr = [ 4, 3, 5, 2, 1, 3, 2, 3 ]; let n = 8; // Function calling quickSortIterative(arr, 0, n - 1); for (let i = 0; i < n; i++) document.write(arr[i] + " "); // This code is contributed by mukesh07. </script>
Echa un vistazo al curso de autoaprendizaje de DSA
Producción:
1 2 2 3 3 3 4 5
Las optimizaciones mencionadas anteriormente para la ordenación rápida recursiva también se pueden aplicar a la versión iterativa.
1) El proceso de partición es el mismo tanto en recursivo como en iterativo. Las mismas técnicas para elegir el pivote óptimo también se pueden aplicar a la versión iterativa.
2) Para reducir el tamaño de la pila, primero presione los índices de la mitad más pequeña.
3) Utilice la ordenación por inserción cuando el tamaño se reduzca por debajo de un umbral calculado experimentalmente.
Referencias:
http://en.wikipedia.org/wiki/Quicksort
Este artículo fue compilado por Aashish Barnwal y revisado por el equipo de GeeksforGeeks. Escriba comentarios si encuentra algo incorrecto o si desea compartir más información sobre el tema tratado anteriormente.
Publicación traducida automáticamente
Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA