Algoritmos de Ordenamiento
Los algoritmos de ordenamiento son un conjunto de instrucciones que toman un arreglo o lista de elementos como entrada y organizan los elementos en un orden específico. Se clasifican en comparativos, que ordenan mediante comparaciones, y no comparativos, que usan propiedades específicas de los datos. Su eficiencia varía según el método, con complejidades desde O(n log n) en algoritmos eficientes hasta O(n²) en los menos óptimos.
Ordenamiento Burbuja
El ordenamiento burbuja es un algoritmo simple que recorre repetidamente la lista, compara elementos adyacentes y los intercambia si están en el orden incorrecto. Este proceso se repite hasta que no se requieren más intercambios, lo que indica que la lista está ordenada.
Complejidad
- Complejidad Temporal:
O(n) mejor caso, O(n²) promedio y peor caso
- Complejidad Espacial:
O(1)
Implementación
public class BubbleSort {
public static void bubbleSort(int[] arr) {
int n = arr.length;
boolean swapped;
// Recorrer el arreglo n veces
for (int i = 0; i < n - 1; i++) {
swapped = false;
// En cada iteración, comparar elementos adyacentes
for (int j = 0; j < n - i - 1; j++) {
// Si el elemento actual es mayor que el siguiente, intercambiarlos
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
swapped = true;
}
}
// Si no hubo intercambios en esta pasada, el arreglo ya está ordenado
if (!swapped) {
break;
}
}
}
// Método principal para probar el algoritmo
public static void main(String[] args) {
int[] arr = {64, 34, 25, 12, 22, 11, 90};
System.out.println("Arreglo original:");
for (int num : arr) {
System.out.print(num + " ");
}
bubbleSort(arr);
System.out.println("
Arreglo ordenado:");
for (int num : arr) {
System.out.print(num + " ");
}
}
}
def bubble_sort(arr):
n = len(arr)
# Recorrer todos los elementos del arreglo
for i in range(n - 1):
swapped = False
# Última i elementos ya están en su lugar correcto
for j in range(0, n - i - 1):
# Comparar elementos adyacentes
if arr[j] > arr[j + 1]:
# Intercambiar si el elemento encontrado es mayor que el siguiente
arr[j], arr[j + 1] = arr[j + 1], arr[j]
swapped = True
# Si no se realizó ningún intercambio en esta iteración, el arreglo ya está ordenado
if not swapped:
break
return arr
# Código de prueba
if __name__ == "__main__":
arr = [64, 34, 25, 12, 22, 11, 90]
print("Arreglo original:", arr)
bubble_sort(arr)
print("Arreglo ordenado:", arr)
function bubbleSort(arr) {
const n = arr.length;
// Recorrer el arreglo n veces
for (let i = 0; i < n - 1; i++) {
let swapped = false;
// En cada iteración, comparar elementos adyacentes
for (let j = 0; j < n - i - 1; j++) {
// Si el elemento actual es mayor que el siguiente, intercambiarlos
if (arr[j] > arr[j + 1]) {
[arr[j], arr[j + 1]] = [arr[j + 1], arr[j]]; // Intercambio usando desestructuración
swapped = true;
}
}
// Si no hubo intercambios en esta pasada, el arreglo ya está ordenado
if (!swapped) {
break;
}
}
return arr;
}
// Código de prueba
const arr = [64, 34, 25, 12, 22, 11, 90];
console.log("Arreglo original:", arr);
bubbleSort(arr);
console.log("Arreglo ordenado:", arr);
function bubbleSort(arr: number[]): number[] {
const n: number = arr.length;
// Recorrer el arreglo n veces
for (let i: number = 0; i < n - 1; i++) {
let swapped: boolean = false;
// En cada iteración, comparar elementos adyacentes
for (let j: number = 0; j < n - i - 1; j++) {
// Si el elemento actual es mayor que el siguiente, intercambiarlos
if (arr[j] > arr[j + 1]) {
[arr[j], arr[j + 1]] = [arr[j + 1], arr[j]]; // Intercambio usando desestructuración
swapped = true;
}
}
// Si no hubo intercambios en esta pasada, el arreglo ya está ordenado
if (!swapped) {
break;
}
}
return arr;
}
// Código de prueba
const arr: number[] = [64, 34, 25, 12, 22, 11, 90];
console.log("Arreglo original:", arr);
bubbleSort(arr);
console.log("Arreglo ordenado:", arr);
package main
import "fmt"
func bubbleSort(arr []int) []int {
n := len(arr)
// Recorrer el arreglo n veces
for i := 0; i < n-1; i++ {
swapped := false
// En cada iteración, comparar elementos adyacentes
for j := 0; j < n-i-1; j++ {
// Si el elemento actual es mayor que el siguiente, intercambiarlos
if arr[j] > arr[j+1] {
// Intercambio de elementos
arr[j], arr[j+1] = arr[j+1], arr[j]
swapped = true
}
}
// Si no hubo intercambios en esta pasada, el arreglo ya está ordenado
if !swapped {
break
}
}
return arr
}
func main() {
arr := []int{64, 34, 25, 12, 22, 11, 90}
fmt.Println("Arreglo original:", arr)
bubbleSort(arr)
fmt.Println("Arreglo ordenado:", arr)
}
#include <stdio.h>
#include <stdbool.h>
// Función para implementar el ordenamiento burbuja
void bubbleSort(int arr[], int n) {
int i, j;
bool swapped;
// Recorrer el arreglo n veces
for (i = 0; i < n - 1; i++) {
swapped = false;
// En cada iteración, comparar elementos adyacentes
for (j = 0; j < n - i - 1; j++) {
// Si el elemento actual es mayor que el siguiente, intercambiarlos
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
swapped = true;
}
}
// Si no hubo intercambios en esta pasada, el arreglo ya está ordenado
if (!swapped) {
break;
}
}
}
// Función para imprimir un arreglo
void printArray(int arr[], int size) {
for (int i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("
");
}
// Programa principal para probar el algoritmo
int main() {
int arr[] = {64, 34, 25, 12, 22, 11, 90};
int n = sizeof(arr) / sizeof(arr[0]);
printf("Arreglo original:
");
printArray(arr, n);
bubbleSort(arr, n);
printf("Arreglo ordenado:
");
printArray(arr, n);
return 0;
}
#include <iostream>
#include <vector>
// Función para implementar el ordenamiento burbuja
void bubbleSort(std::vector<int>& arr) {
int n = arr.size();
bool swapped;
// Recorrer el arreglo n veces
for (int i = 0; i < n - 1; i++) {
swapped = false;
// En cada iteración, comparar elementos adyacentes
for (int j = 0; j < n - i - 1; j++) {
// Si el elemento actual es mayor que el siguiente, intercambiarlos
if (arr[j] > arr[j + 1]) {
std::swap(arr[j], arr[j + 1]);
swapped = true;
}
}
// Si no hubo intercambios en esta pasada, el arreglo ya está ordenado
if (!swapped) {
break;
}
}
}
// Función para imprimir un vector
void printVector(const std::vector<int>& arr) {
for (int num : arr) {
std::cout << num << " ";
}
std::cout << std::endl;
}
// Programa principal para probar el algoritmo
int main() {
std::vector<int> arr = {64, 34, 25, 12, 22, 11, 90};
std::cout << "Arreglo original: " << std::endl;
printVector(arr);
bubbleSort(arr);
std::cout << "Arreglo ordenado: " << std::endl;
printVector(arr);
return 0;
}
using System;
class BubbleSort {
// Función para implementar el ordenamiento burbuja
static void Sort(int[] arr) {
int n = arr.Length;
bool swapped;
// Recorrer el arreglo n veces
for (int i = 0; i < n - 1; i++) {
swapped = false;
// En cada iteración, comparar elementos adyacentes
for (int j = 0; j < n - i - 1; j++) {
// Si el elemento actual es mayor que el siguiente, intercambiarlos
if (arr[j] > arr[j + 1]) {
// Intercambio de elementos
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
swapped = true;
}
}
// Si no hubo intercambios en esta pasada, el arreglo ya está ordenado
if (!swapped) {
break;
}
}
}
// Función para imprimir un arreglo
static void PrintArray(int[] arr) {
foreach (int num in arr) {
Console.Write(num + " ");
}
Console.WriteLine();
}
// Programa principal para probar el algoritmo
static void Main() {
int[] arr = {64, 34, 25, 12, 22, 11, 90};
Console.WriteLine("Arreglo original:");
PrintArray(arr);
Sort(arr);
Console.WriteLine("Arreglo ordenado:");
PrintArray(arr);
}
}
Ordenamiento por Selección
El ordenamiento por selección divide el arreglo en dos partes: la submatriz ordenada y la submatriz no ordenada. En cada iteración, encuentra el elemento mínimo de la submatriz no ordenada y lo intercambia con el elemento en la primera posición de la submatriz no ordenada.
Complejidad
- Complejidad Temporal:
O(n²) mejor, promedio y peor caso
- Complejidad Espacial:
O(1)
Implementación
public class SelectionSort {
public static void selectionSort(int[] arr) {
int n = arr.length;
// Recorrer todo el arreglo
for (int i = 0; i < n - 1; i++) {
// Encontrar el índice del elemento mínimo en el subarreglo no ordenado
int minIndex = i;
for (int j = i + 1; j < n; j++) {
if (arr[j] < arr[minIndex]) {
minIndex = j;
}
}
// Intercambiar el elemento mínimo encontrado con el primer elemento
int temp = arr[minIndex];
arr[minIndex] = arr[i];
arr[i] = temp;
}
}
// Método principal para probar el algoritmo
public static void main(String[] args) {
int[] arr = {64, 25, 12, 22, 11};
System.out.println("Arreglo original:");
for (int num : arr) {
System.out.print(num + " ");
}
selectionSort(arr);
System.out.println("
Arreglo ordenado:");
for (int num : arr) {
System.out.print(num + " ");
}
}
}
def selection_sort(arr):
n = len(arr)
# Recorrer todo el arreglo
for i in range(n - 1):
# Encontrar el índice del elemento mínimo en el subarreglo no ordenado
min_idx = i
for j in range(i + 1, n):
if arr[j] < arr[min_idx]:
min_idx = j
# Intercambiar el elemento mínimo encontrado con el primer elemento
arr[i], arr[min_idx] = arr[min_idx], arr[i]
return arr
# Código de prueba
if __name__ == "__main__":
arr = [64, 25, 12, 22, 11]
print("Arreglo original:", arr)
selection_sort(arr)
print("Arreglo ordenado:", arr)
function selectionSort(arr) {
const n = arr.length;
// Recorrer todo el arreglo
for (let i = 0; i < n - 1; i++) {
// Encontrar el índice del elemento mínimo en el subarreglo no ordenado
let minIndex = i;
for (let j = i + 1; j < n; j++) {
if (arr[j] < arr[minIndex]) {
minIndex = j;
}
}
// Intercambiar el elemento mínimo encontrado con el primer elemento
if (minIndex !== i) {
[arr[i], arr[minIndex]] = [arr[minIndex], arr[i]];
}
}
return arr;
}
// Código de prueba
const arr = [64, 25, 12, 22, 11];
console.log("Arreglo original:", arr);
selectionSort(arr);
console.log("Arreglo ordenado:", arr);
function selectionSort(arr: number[]): number[] {
const n: number = arr.length;
// Recorrer todo el arreglo
for (let i: number = 0; i < n - 1; i++) {
// Encontrar el índice del elemento mínimo en el subarreglo no ordenado
let minIndex: number = i;
for (let j: number = i + 1; j < n; j++) {
if (arr[j] < arr[minIndex]) {
minIndex = j;
}
}
// Intercambiar el elemento mínimo encontrado con el primer elemento
if (minIndex !== i) {
[arr[i], arr[minIndex]] = [arr[minIndex], arr[i]];
}
}
return arr;
}
// Código de prueba
const arr: number[] = [64, 25, 12, 22, 11];
console.log("Arreglo original:", arr);
selectionSort(arr);
console.log("Arreglo ordenado:", arr);
package main
import "fmt"
func selectionSort(arr []int) []int {
n := len(arr)
// Recorrer todo el arreglo
for i := 0; i < n-1; i++ {
// Encontrar el índice del elemento mínimo en el subarreglo no ordenado
minIndex := i
for j := i + 1; j < n; j++ {
if arr[j] < arr[minIndex] {
minIndex = j
}
}
// Intercambiar el elemento mínimo encontrado con el primer elemento
if minIndex != i {
arr[i], arr[minIndex] = arr[minIndex], arr[i]
}
}
return arr
}
func main() {
arr := []int{64, 25, 12, 22, 11}
fmt.Println("Arreglo original:", arr)
selectionSort(arr)
fmt.Println("Arreglo ordenado:", arr)
}
#include <stdio.h>
// Función para implementar el ordenamiento por selección
void selectionSort(int arr[], int n) {
int i, j, min_idx;
// Recorrer todo el arreglo
for (i = 0; i < n - 1; i++) {
// Encontrar el índice del elemento mínimo en el subarreglo no ordenado
min_idx = i;
for (j = i + 1; j < n; j++) {
if (arr[j] < arr[min_idx]) {
min_idx = j;
}
}
// Intercambiar el elemento mínimo encontrado con el primer elemento
if (min_idx != i) {
int temp = arr[min_idx];
arr[min_idx] = arr[i];
arr[i] = temp;
}
}
}
// Función para imprimir un arreglo
void printArray(int arr[], int size) {
for (int i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("
");
}
// Programa principal para probar el algoritmo
int main() {
int arr[] = {64, 25, 12, 22, 11};
int n = sizeof(arr) / sizeof(arr[0]);
printf("Arreglo original:
");
printArray(arr, n);
selectionSort(arr, n);
printf("Arreglo ordenado:
");
printArray(arr, n);
return 0;
}
#include <iostream>
#include <vector>
// Función para implementar el ordenamiento por selección
void selectionSort(std::vector<int>& arr) {
int n = arr.size();
// Recorrer todo el arreglo
for (int i = 0; i < n - 1; i++) {
// Encontrar el índice del elemento mínimo en el subarreglo no ordenado
int min_idx = i;
for (int j = i + 1; j < n; j++) {
if (arr[j] < arr[min_idx]) {
min_idx = j;
}
}
// Intercambiar el elemento mínimo encontrado con el primer elemento
if (min_idx != i) {
std::swap(arr[i], arr[min_idx]);
}
}
}
// Función para imprimir un vector
void printVector(const std::vector<int>& arr) {
for (int num : arr) {
std::cout << num << " ";
}
std::cout << std::endl;
}
// Programa principal para probar el algoritmo
int main() {
std::vector<int> arr = {64, 25, 12, 22, 11};
std::cout << "Arreglo original: " << std::endl;
printVector(arr);
selectionSort(arr);
std::cout << "Arreglo ordenado: " << std::endl;
printVector(arr);
return 0;
}
using System;
class SelectionSort {
// Función para implementar el ordenamiento por selección
static void Sort(int[] arr) {
int n = arr.Length;
// Recorrer todo el arreglo
for (int i = 0; i < n - 1; i++) {
// Encontrar el índice del elemento mínimo en el subarreglo no ordenado
int minIndex = i;
for (int j = i + 1; j < n; j++) {
if (arr[j] < arr[minIndex]) {
minIndex = j;
}
}
// Intercambiar el elemento mínimo encontrado con el primer elemento
if (minIndex != i) {
int temp = arr[minIndex];
arr[minIndex] = arr[i];
arr[i] = temp;
}
}
}
// Función para imprimir un arreglo
static void PrintArray(int[] arr) {
foreach (int num in arr) {
Console.Write(num + " ");
}
Console.WriteLine();
}
// Programa principal para probar el algoritmo
static void Main() {
int[] arr = {64, 25, 12, 22, 11};
Console.WriteLine("Arreglo original:");
PrintArray(arr);
Sort(arr);
Console.WriteLine("Arreglo ordenado:");
PrintArray(arr);
}
}
Ordenamiento por Inserción
El ordenamiento por inserción construye la lista ordenada final un elemento a la vez. Se toma cada elemento de la lista original y se inserta en su posición correcta dentro de una nueva lista ordenada, similar a cómo se ordenan las cartas en una mano de póker.
Complejidad
- Complejidad Temporal:
O(n) mejor, O(n²) promedio y peor caso
- Complejidad Espacial:
O(1)
Implementación
public class InsertionSort {
public static void insertionSort(int[] arr) {
int n = arr.length;
// Recorrer el arreglo desde el segundo elemento
for (int i = 1; i < n; i++) {
int key = arr[i]; // Elemento a insertar en la parte ordenada
int j = i - 1;
// Mover elementos de arr[0..i-1] que son mayores que key
// a una posición adelante de su posición actual
while (j >= 0 && arr[j] > key) {
arr[j + 1] = arr[j];
j = j - 1;
}
arr[j + 1] = key; // Insertar key en su posición correcta
}
}
// Método principal para probar el algoritmo
public static void main(String[] args) {
int[] arr = {12, 11, 13, 5, 6};
System.out.println("Arreglo original:");
for (int num : arr) {
System.out.print(num + " ");
}
insertionSort(arr);
System.out.println("
Arreglo ordenado:");
for (int num : arr) {
System.out.print(num + " ");
}
}
}
def insertion_sort(arr):
# Recorrer desde el segundo elemento hasta el último
for i in range(1, len(arr)):
key = arr[i] # Elemento a insertar en la parte ordenada
j = i - 1
# Mover elementos de arr[0..i-1] que son mayores que key
# a una posición adelante de su posición actual
while j >= 0 and arr[j] > key:
arr[j + 1] = arr[j]
j -= 1
arr[j + 1] = key # Insertar key en su posición correcta
return arr
# Código de prueba
if __name__ == "__main__":
arr = [12, 11, 13, 5, 6]
print("Arreglo original:", arr)
insertion_sort(arr)
print("Arreglo ordenado:", arr)
function insertionSort(arr) {
const n = arr.length;
// Recorrer desde el segundo elemento hasta el último
for (let i = 1; i < n; i++) {
let key = arr[i]; // Elemento a insertar en la parte ordenada
let j = i - 1;
// Mover elementos de arr[0..i-1] que son mayores que key
// a una posición adelante de su posición actual
while (j >= 0 && arr[j] > key) {
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = key; // Insertar key en su posición correcta
}
return arr;
}
// Código de prueba
const arr = [12, 11, 13, 5, 6];
console.log("Arreglo original:", arr);
insertionSort(arr);
console.log("Arreglo ordenado:", arr);
function insertionSort(arr: number[]): number[] {
const n: number = arr.length;
// Recorrer desde el segundo elemento hasta el último
for (let i: number = 1; i < n; i++) {
let key: number = arr[i]; // Elemento a insertar en la parte ordenada
let j: number = i - 1;
// Mover elementos de arr[0..i-1] que son mayores que key
// a una posición adelante de su posición actual
while (j >= 0 && arr[j] > key) {
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = key; // Insertar key en su posición correcta
}
return arr;
}
// Código de prueba
const arr: number[] = [12, 11, 13, 5, 6];
console.log("Arreglo original:", arr);
insertionSort(arr);
console.log("Arreglo ordenado:", arr);
package main
import "fmt"
func insertionSort(arr []int) []int {
n := len(arr)
// Recorrer desde el segundo elemento hasta el último
for i := 1; i < n; i++ {
key := arr[i] // Elemento a insertar en la parte ordenada
j := i - 1
// Mover elementos de arr[0..i-1] que son mayores que key
// a una posición adelante de su posición actual
for j >= 0 && arr[j] > key {
arr[j+1] = arr[j]
j--
}
arr[j+1] = key // Insertar key en su posición correcta
}
return arr
}
func main() {
arr := []int{12, 11, 13, 5, 6}
fmt.Println("Arreglo original:", arr)
insertionSort(arr)
fmt.Println("Arreglo ordenado:", arr)
}
#include <stdio.h>
// Función para implementar el ordenamiento por inserción
void insertionSort(int arr[], int n) {
int i, key, j;
// Recorrer desde el segundo elemento hasta el último
for (i = 1; i < n; i++) {
key = arr[i]; // Elemento a insertar en la parte ordenada
j = i - 1;
// Mover elementos de arr[0..i-1] que son mayores que key
// a una posición adelante de su posición actual
while (j >= 0 && arr[j] > key) {
arr[j + 1] = arr[j];
j = j - 1;
}
arr[j + 1] = key; // Insertar key en su posición correcta
}
}
// Función para imprimir un arreglo
void printArray(int arr[], int n) {
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("
");
}
// Programa principal para probar el algoritmo
int main() {
int arr[] = {12, 11, 13, 5, 6};
int n = sizeof(arr) / sizeof(arr[0]);
printf("Arreglo original:
");
printArray(arr, n);
insertionSort(arr, n);
printf("Arreglo ordenado:
");
printArray(arr, n);
return 0;
}
#include <iostream>
#include <vector>
// Función para implementar el ordenamiento por inserción
void insertionSort(std::vector<int>& arr) {
int n = arr.size();
// Recorrer desde el segundo elemento hasta el último
for (int i = 1; i < n; i++) {
int key = arr[i]; // Elemento a insertar en la parte ordenada
int j = i - 1;
// Mover elementos de arr[0..i-1] que son mayores que key
// a una posición adelante de su posición actual
while (j >= 0 && arr[j] > key) {
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = key; // Insertar key en su posición correcta
}
}
// Función para imprimir un vector
void printVector(const std::vector<int>& arr) {
for (int num : arr) {
std::cout << num << " ";
}
std::cout << std::endl;
}
// Programa principal para probar el algoritmo
int main() {
std::vector<int> arr = {12, 11, 13, 5, 6};
std::cout << "Arreglo original: " << std::endl;
printVector(arr);
insertionSort(arr);
std::cout << "Arreglo ordenado: " << std::endl;
printVector(arr);
return 0;
}
using System;
class InsertionSort {
// Función para implementar el ordenamiento por inserción
static void Sort(int[] arr) {
int n = arr.Length;
// Recorrer desde el segundo elemento hasta el último
for (int i = 1; i < n; i++) {
int key = arr[i]; // Elemento a insertar en la parte ordenada
int j = i - 1;
// Mover elementos de arr[0..i-1] que son mayores que key
// a una posición adelante de su posición actual
while (j >= 0 && arr[j] > key) {
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = key; // Insertar key en su posición correcta
}
}
// Función para imprimir un arreglo
static void PrintArray(int[] arr) {
foreach (int num in arr) {
Console.Write(num + " ");
}
Console.WriteLine();
}
// Programa principal para probar el algoritmo
static void Main() {
int[] arr = {12, 11, 13, 5, 6};
Console.WriteLine("Arreglo original:");
PrintArray(arr);
Sort(arr);
Console.WriteLine("Arreglo ordenado:");
PrintArray(arr);
}
}
Ordenamiento por Fusión
El ordenamiento por fusión es un algoritmo de tipo ''divide y vencerás'' que divide la lista en mitades, ordena cada mitad recursivamente y luego fusiona las mitades ordenadas. Este algoritmo es estable, lo que significa que preserva el orden relativo de elementos iguales.
Complejidad
- Complejidad Temporal:
O(n log n) mejor, promedio y peor caso
- Complejidad Espacial:
O(n)
Implementación
public class MergeSort {
// Función principal de ordenamiento por fusión
public static void mergeSort(int[] arr, int left, int right) {
if (left < right) {
// Encuentra el punto medio del arreglo
int mid = left + (right - left) / 2;
// Ordena recursivamente la primera y segunda mitad
mergeSort(arr, left, mid);
mergeSort(arr, mid + 1, right);
// Fusiona las mitades ordenadas
merge(arr, left, mid, right);
}
}
// Función para fusionar dos subarreglos de arr[]
public static void merge(int[] arr, int left, int mid, int right) {
// Calcula el tamaño de los subarreglos temporales
int n1 = mid - left + 1;
int n2 = right - mid;
// Crea arreglos temporales
int[] L = new int[n1];
int[] R = new int[n2];
// Copia los datos a los arreglos temporales
for (int i = 0; i < n1; ++i) {
L[i] = arr[left + i];
}
for (int j = 0; j < n2; ++j) {
R[j] = arr[mid + 1 + j];
}
// Fusiona los arreglos temporales
// Índices iniciales de los subarreglos
int i = 0, j = 0;
// Índice inicial del subarreglo fusionado
int k = left;
while (i < n1 && j < n2) {
if (L[i] <= R[j]) {
arr[k] = L[i];
i++;
} else {
arr[k] = R[j];
j++;
}
k++;
}
// Copia los elementos restantes de L[], si hay alguno
while (i < n1) {
arr[k] = L[i];
i++;
k++;
}
// Copia los elementos restantes de R[], si hay alguno
while (j < n2) {
arr[k] = R[j];
j++;
k++;
}
}
// Método auxiliar para iniciar el ordenamiento
public static void sort(int[] arr) {
mergeSort(arr, 0, arr.length - 1);
}
// Método principal para probar el algoritmo
public static void main(String[] args) {
int[] arr = {12, 11, 13, 5, 6, 7};
System.out.println("Arreglo original:");
for (int num : arr) {
System.out.print(num + " ");
}
sort(arr);
System.out.println("
Arreglo ordenado:");
for (int num : arr) {
System.out.print(num + " ");
}
}
}
def merge_sort(arr):
if len(arr) > 1:
# Encuentra el punto medio del arreglo
mid = len(arr) // 2
# Divide el arreglo en dos mitades
L = arr[:mid]
R = arr[mid:]
# Ordena recursivamente la primera y segunda mitad
merge_sort(L)
merge_sort(R)
# Inicializa índices para la fusión
i = j = k = 0
# Fusiona las mitades ordenadas
while i < len(L) and j < len(R):
if L[i] <= R[j]:
arr[k] = L[i]
i += 1
else:
arr[k] = R[j]
j += 1
k += 1
# Verifica si quedan elementos en L
while i < len(L):
arr[k] = L[i]
i += 1
k += 1
# Verifica si quedan elementos en R
while j < len(R):
arr[k] = R[j]
j += 1
k += 1
return arr
# Código de prueba
if __name__ == "__main__":
arr = [12, 11, 13, 5, 6, 7]
print("Arreglo original:", arr)
merge_sort(arr)
print("Arreglo ordenado:", arr)
function mergeSort(arr) {
if (arr.length <= 1) {
return arr;
}
// Encuentra el punto medio del arreglo
const mid = Math.floor(arr.length / 2);
// Divide el arreglo en dos mitades
const left = arr.slice(0, mid);
const right = arr.slice(mid);
// Fusiona recursivamente las mitades ordenadas
return merge(mergeSort(left), mergeSort(right));
}
// Función para fusionar dos subarreglos ordenados
function merge(left, right) {
let result = [];
let leftIndex = 0;
let rightIndex = 0;
// Compara los elementos de ambos arreglos y los agrega en orden
while (leftIndex < left.length && rightIndex < right.length) {
if (left[leftIndex] < right[rightIndex]) {
result.push(left[leftIndex]);
leftIndex++;
} else {
result.push(right[rightIndex]);
rightIndex++;
}
}
// Concatena los elementos restantes
return result.concat(left.slice(leftIndex)).concat(right.slice(rightIndex));
}
// Código de prueba
const arr = [12, 11, 13, 5, 6, 7];
console.log("Arreglo original:", arr);
const sortedArr = mergeSort([...arr]); // Crea una copia para no modificar el original
console.log("Arreglo ordenado:", sortedArr);
function mergeSort(arr: number[]): number[] {
if (arr.length <= 1) {
return arr;
}
// Encuentra el punto medio del arreglo
const mid: number = Math.floor(arr.length / 2);
// Divide el arreglo en dos mitades
const left: number[] = arr.slice(0, mid);
const right: number[] = arr.slice(mid);
// Fusiona recursivamente las mitades ordenadas
return merge(mergeSort(left), mergeSort(right));
}
// Función para fusionar dos subarreglos ordenados
function merge(left: number[], right: number[]): number[] {
let result: number[] = [];
let leftIndex: number = 0;
let rightIndex: number = 0;
// Compara los elementos de ambos arreglos y los agrega en orden
while (leftIndex < left.length && rightIndex < right.length) {
if (left[leftIndex] < right[rightIndex]) {
result.push(left[leftIndex]);
leftIndex++;
} else {
result.push(right[rightIndex]);
rightIndex++;
}
}
// Concatena los elementos restantes
return result.concat(left.slice(leftIndex)).concat(right.slice(rightIndex));
}
// Código de prueba
const arr: number[] = [12, 11, 13, 5, 6, 7];
console.log("Arreglo original:", arr);
const sortedArr: number[] = mergeSort([...arr]); // Crea una copia para no modificar el original
console.log("Arreglo ordenado:", sortedArr);
package main
import "fmt"
func mergeSort(arr []int) []int {
if len(arr) <= 1 {
return arr
}
// Encuentra el punto medio del arreglo
mid := len(arr) / 2
// Divide el arreglo en dos mitades
left := make([]int, mid)
right := make([]int, len(arr)-mid)
copy(left, arr[:mid])
copy(right, arr[mid:])
// Ordena recursivamente la primera y segunda mitad
left = mergeSort(left)
right = mergeSort(right)
// Fusiona las mitades ordenadas
return merge(left, right)
}
// Función para fusionar dos subarreglos ordenados
func merge(left, right []int) []int {
result := make([]int, 0, len(left)+len(right))
// Mientras haya elementos en ambos arreglos
for len(left) > 0 && len(right) > 0 {
if left[0] <= right[0] {
result = append(result, left[0])
left = left[1:]
} else {
result = append(result, right[0])
right = right[1:]
}
}
// Agrega los elementos restantes
result = append(result, left...)
result = append(result, right...)
return result
}
func main() {
arr := []int{12, 11, 13, 5, 6, 7}
fmt.Println("Arreglo original:", arr)
sortedArr := mergeSort(arr) // Retorna un nuevo arreglo ordenado
fmt.Println("Arreglo ordenado:", sortedArr)
}
#include <stdio.h>
#include <stdlib.h>
// Función para fusionar dos subarreglos de arr[]
void merge(int arr[], int left, int mid, int right) {
int i, j, k;
int n1 = mid - left + 1;
int n2 = right - mid;
// Crea arreglos temporales
int* L = (int*)malloc(n1 * sizeof(int));
int* R = (int*)malloc(n2 * sizeof(int));
// Copia los datos a los arreglos temporales L[] y R[]
for (i = 0; i < n1; i++) {
L[i] = arr[left + i];
}
for (j = 0; j < n2; j++) {
R[j] = arr[mid + 1 + j];
}
// Fusiona los arreglos temporales de vuelta en arr[left..right]
i = 0; // Índice inicial del primer subarreglo
j = 0; // Índice inicial del segundo subarreglo
k = left; // Índice inicial del subarreglo fusionado
while (i < n1 && j < n2) {
if (L[i] <= R[j]) {
arr[k] = L[i];
i++;
} else {
arr[k] = R[j];
j++;
}
k++;
}
// Copia los elementos restantes de L[], si hay alguno
while (i < n1) {
arr[k] = L[i];
i++;
k++;
}
// Copia los elementos restantes de R[], si hay alguno
while (j < n2) {
arr[k] = R[j];
j++;
k++;
}
// Libera la memoria de los arreglos temporales
free(L);
free(R);
}
// Función principal de ordenamiento por fusión
void mergeSort(int arr[], int left, int right) {
if (left < right) {
// Encuentra el punto medio
int mid = left + (right - left) / 2;
// Ordena la primera y segunda mitad
mergeSort(arr, left, mid);
mergeSort(arr, mid + 1, right);
// Fusiona las mitades ordenadas
merge(arr, left, mid, right);
}
}
// Función para imprimir un arreglo
void printArray(int arr[], int size) {
for (int i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("
");
}
// Programa principal para probar el algoritmo
int main() {
int arr[] = {12, 11, 13, 5, 6, 7};
int n = sizeof(arr) / sizeof(arr[0]);
printf("Arreglo original:
");
printArray(arr, n);
mergeSort(arr, 0, n - 1);
printf("Arreglo ordenado:
");
printArray(arr, n);
return 0;
}
#include <iostream>
#include <vector>
// Función para fusionar dos subarreglos ordenados
void merge(std::vector<int>& arr, int left, int mid, int right) {
// Calcula los tamaños de los subarreglos temporales
int n1 = mid - left + 1;
int n2 = right - mid;
// Crea arreglos temporales
std::vector<int> L(n1), R(n2);
// Copia los datos a los arreglos temporales
for (int i = 0; i < n1; i++) {
L[i] = arr[left + i];
}
for (int j = 0; j < n2; j++) {
R[j] = arr[mid + 1 + j];
}
// Fusiona los arreglos temporales
int i = 0; // Índice inicial para el primer subarreglo
int j = 0; // Índice inicial para el segundo subarreglo
int k = left; // Índice inicial para el subarreglo fusionado
while (i < n1 && j < n2) {
if (L[i] <= R[j]) {
arr[k] = L[i];
i++;
} else {
arr[k] = R[j];
j++;
}
k++;
}
// Copia los elementos restantes de L[], si hay alguno
while (i < n1) {
arr[k] = L[i];
i++;
k++;
}
// Copia los elementos restantes de R[], si hay alguno
while (j < n2) {
arr[k] = R[j];
j++;
k++;
}
}
// Función principal de ordenamiento por fusión
void mergeSort(std::vector<int>& arr, int left, int right) {
if (left < right) {
// Encuentra el punto medio
int mid = left + (right - left) / 2;
// Ordena la primera y segunda mitad
mergeSort(arr, left, mid);
mergeSort(arr, mid + 1, right);
// Fusiona las mitades ordenadas
merge(arr, left, mid, right);
}
}
// Función auxiliar para iniciar el ordenamiento
void sort(std::vector<int>& arr) {
mergeSort(arr, 0, arr.size() - 1);
}
// Función para imprimir un vector
void printVector(const std::vector<int>& arr) {
for (int num : arr) {
std::cout << num << " ";
}
std::cout << std::endl;
}
// Programa principal para probar el algoritmo
int main() {
std::vector<int> arr = {12, 11, 13, 5, 6, 7};
std::cout << "Arreglo original: " << std::endl;
printVector(arr);
sort(arr);
std::cout << "Arreglo ordenado: " << std::endl;
printVector(arr);
return 0;
}
using System;
class MergeSort {
// Función principal de ordenamiento por fusión
static void Sort(int[] arr, int left, int right) {
if (left < right) {
// Encuentra el punto medio
int mid = left + (right - left) / 2;
// Ordena la primera y segunda mitad
Sort(arr, left, mid);
Sort(arr, mid + 1, right);
// Fusiona las mitades ordenadas
Merge(arr, left, mid, right);
}
}
// Función para fusionar dos subarreglos de arr[]
static void Merge(int[] arr, int left, int mid, int right) {
// Calcula los tamaños de los subarreglos temporales
int n1 = mid - left + 1;
int n2 = right - mid;
// Crea arreglos temporales
int[] L = new int[n1];
int[] R = new int[n2];
// Copia los datos a los arreglos temporales
for (int i = 0; i < n1; i++) {
L[i] = arr[left + i];
}
for (int j = 0; j < n2; j++) {
R[j] = arr[mid + 1 + j];
}
// Fusiona los arreglos temporales
int i = 0; // Índice inicial para el primer subarreglo
int j = 0; // Índice inicial para el segundo subarreglo
int k = left; // Índice inicial para el subarreglo fusionado
while (i < n1 && j < n2) {
if (L[i] <= R[j]) {
arr[k] = L[i];
i++;
} else {
arr[k] = R[j];
j++;
}
k++;
}
// Copia los elementos restantes de L[], si hay alguno
while (i < n1) {
arr[k] = L[i];
i++;
k++;
}
// Copia los elementos restantes de R[], si hay alguno
while (j < n2) {
arr[k] = R[j];
j++;
k++;
}
}
// Método auxiliar para iniciar el ordenamiento
static void MergeSortArray(int[] arr) {
Sort(arr, 0, arr.Length - 1);
}
// Función para imprimir un arreglo
static void PrintArray(int[] arr) {
foreach (int num in arr) {
Console.Write(num + " ");
}
Console.WriteLine();
}
// Programa principal para probar el algoritmo
static void Main() {
int[] arr = {12, 11, 13, 5, 6, 7};
Console.WriteLine("Arreglo original:");
PrintArray(arr);
MergeSortArray(arr);
Console.WriteLine("Arreglo ordenado:");
PrintArray(arr);
}
}
Ordenamiento Rápido
El ordenamiento rápido (QuickSort) es un algoritmo de tipo ''divide y vencerás'' que selecciona un elemento como pivote y particiona el arreglo alrededor del pivote. El algoritmo coloca todos los elementos menores que el pivote a su izquierda y todos los elementos mayores a su derecha, luego ordena recursivamente las submatrices.
Complejidad
- Complejidad Temporal:
O(n log n) promedio y mejor caso, O(n²) peor caso
- Complejidad Espacial:
O(log n) por recursión
Implementación
public class QuickSort {
// Función para intercambiar dos elementos
public static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
// Función para particionar el arreglo y devolver el índice del pivote
public static int partition(int[] arr, int low, int high) {
// Selecciona el último elemento como pivote
int pivot = arr[high];
// Índice del elemento más pequeño e indica la
// posición correcta del pivote hasta ahora
int i = (low - 1);
for (int j = low; j <= high - 1; j++) {
// Si el elemento actual es menor que el pivote
if (arr[j] < pivot) {
i++;
swap(arr, i, j);
}
}
swap(arr, i + 1, high);
return (i + 1);
}
// Función principal de ordenamiento rápido
public static void quickSort(int[] arr, int low, int high) {
if (low < high) {
// pi es el índice de partición, arr[pi] está ahora en la posición correcta
int pi = partition(arr, low, high);
// Ordena recursivamente los elementos antes y después de la partición
quickSort(arr, low, pi - 1);
quickSort(arr, pi + 1, high);
}
}
// Método auxiliar para iniciar el ordenamiento
public static void sort(int[] arr) {
quickSort(arr, 0, arr.length - 1);
}
// Método principal para probar el algoritmo
public static void main(String[] args) {
int[] arr = {10, 7, 8, 9, 1, 5};
System.out.println("Arreglo original:");
for (int num : arr) {
System.out.print(num + " ");
}
sort(arr);
System.out.println("
Arreglo ordenado:");
for (int num : arr) {
System.out.print(num + " ");
}
}
}
def quick_sort(arr):
# Función interna para ordenar una parte específica del arreglo
def _quick_sort(arr, low, high):
if low < high:
# pi es el índice de partición, arr[pi] está ahora en la posición correcta
pi = partition(arr, low, high)
# Ordena recursivamente los elementos antes y después de la partición
_quick_sort(arr, low, pi - 1)
_quick_sort(arr, pi + 1, high)
# Función para particionar el arreglo y devolver el índice del pivote
def partition(arr, low, high):
# Selecciona el último elemento como pivote
pivot = arr[high]
# Índice del elemento más pequeño e indica la
# posición correcta del pivote hasta ahora
i = low - 1
for j in range(low, high):
# Si el elemento actual es menor que el pivote
if arr[j] < pivot:
i += 1
arr[i], arr[j] = arr[j], arr[i]
# Coloca el pivote en su posición correcta
arr[i + 1], arr[high] = arr[high], arr[i + 1]
return i + 1
_quick_sort(arr, 0, len(arr) - 1)
return arr
# Código de prueba
if __name__ == "__main__":
arr = [10, 7, 8, 9, 1, 5]
print("Arreglo original:", arr)
quick_sort(arr)
print("Arreglo ordenado:", arr)
function quickSort(arr, low = 0, high = arr.length - 1) {
if (low < high) {
// pi es el índice de partición, arr[pi] está ahora en la posición correcta
const pi = partition(arr, low, high);
// Ordena recursivamente los elementos antes y después de la partición
quickSort(arr, low, pi - 1);
quickSort(arr, pi + 1, high);
}
return arr;
}
// Función para particionar el arreglo y devolver el índice del pivote
function partition(arr, low, high) {
// Selecciona el último elemento como pivote
const pivot = arr[high];
// Índice del elemento más pequeño e indica la
// posición correcta del pivote hasta ahora
let i = low - 1;
for (let j = low; j < high; j++) {
// Si el elemento actual es menor que el pivote
if (arr[j] < pivot) {
i++;
[arr[i], arr[j]] = [arr[j], arr[i]]; // Intercambio
}
}
// Coloca el pivote en su posición correcta
[arr[i + 1], arr[high]] = [arr[high], arr[i + 1]];
return i + 1;
}
// Código de prueba
const arr = [10, 7, 8, 9, 1, 5];
console.log("Arreglo original:", arr);
quickSort(arr);
console.log("Arreglo ordenado:", arr);
function quickSort(arr: number[], low: number = 0, high: number = arr.length - 1): number[] {
if (low < high) {
// pi es el índice de partición, arr[pi] está ahora en la posición correcta
const pi: number = partition(arr, low, high);
// Ordena recursivamente los elementos antes y después de la partición
quickSort(arr, low, pi - 1);
quickSort(arr, pi + 1, high);
}
return arr;
}
// Función para particionar el arreglo y devolver el índice del pivote
function partition(arr: number[], low: number, high: number): number {
// Selecciona el último elemento como pivote
const pivot: number = arr[high];
// Índice del elemento más pequeño e indica la
// posición correcta del pivote hasta ahora
let i: number = low - 1;
for (let j: number = low; j < high; j++) {
// Si el elemento actual es menor que el pivote
if (arr[j] < pivot) {
i++;
[arr[i], arr[j]] = [arr[j], arr[i]]; // Intercambio
}
}
// Coloca el pivote en su posición correcta
[arr[i + 1], arr[high]] = [arr[high], arr[i + 1]];
return i + 1;
}
// Código de prueba
const arr: number[] = [10, 7, 8, 9, 1, 5];
console.log("Arreglo original:", arr);
quickSort(arr);
console.log("Arreglo ordenado:", arr);
package main
import (
"fmt"
)
// Función para particionar el arreglo
func partition(arr []int, low, high int) int {
// Seleccionar el último elemento como pivote
pivot := arr[high]
// Índice del elemento más pequeño
i := low - 1
// Recorrer todos los elementos del subarreglo
for j := low; j < high; j++ {
// Si el elemento actual es menor o igual al pivote
if arr[j] <= pivot {
// Incrementar índice de elementos pequeños
i++
// Intercambiar elementos
arr[i], arr[j] = arr[j], arr[i]
}
}
// Colocar pivote en posición correcta
arr[i+1], arr[high] = arr[high], arr[i+1]
// Devolver índice del pivote
return i + 1
}
// Función QuickSort recursiva
func quickSort(arr []int, low, high int) {
// Verificar si hay más de un elemento para ordenar
if low < high {
// 1. DIVIDIR: Particionar el arreglo y obtener el índice del pivote
pivotIndex := partition(arr, low, high)
// 2. CONQUISTAR: Ordenar recursivamente las sublistas
// Ordenar sublista izquierda (menores que pivote)
quickSort(arr, low, pivotIndex-1)
// Ordenar sublista derecha (mayores que pivote)
quickSort(arr, pivotIndex+1, high)
}
}
func main() {
// Arreglo de ejemplo
arr := []int{10, 7, 8, 9, 1, 5}
fmt.Println("Arreglo original:", arr)
// Ejecutar QuickSort
quickSort(arr, 0, len(arr)-1)
fmt.Println("Arreglo ordenado:", arr)
}
#include <stdio.h>
// Función para intercambiar dos elementos
void swap(int* a, int* b) {
int temp = *a;
*a = *b;
*b = temp;
}
// Función para particionar el arreglo
int partition(int arr[], int low, int high) {
// Seleccionar el último elemento como pivote
int pivot = arr[high];
// Índice del elemento más pequeño
int i = low - 1;
// Recorrer todos los elementos del subarreglo
for (int j = low; j < high; j++) {
// Si el elemento actual es menor o igual al pivote
if (arr[j] <= pivot) {
// Incrementar índice de elementos pequeños
i++;
// Intercambiar elementos
swap(&arr[i], &arr[j]);
}
}
// Colocar pivote en posición correcta
swap(&arr[i + 1], &arr[high]);
// Devolver índice del pivote
return i + 1;
}
// Función QuickSort recursiva
void quickSort(int arr[], int low, int high) {
// Verificar si hay más de un elemento para ordenar
if (low < high) {
// 1. DIVIDIR: Particionar el arreglo y obtener el índice del pivote
int pivotIndex = partition(arr, low, high);
// 2. CONQUISTAR: Ordenar recursivamente las sublistas
// Ordenar sublista izquierda (menores que pivote)
quickSort(arr, low, pivotIndex - 1);
// Ordenar sublista derecha (mayores que pivote)
quickSort(arr, pivotIndex + 1, high);
}
}
// Función para imprimir arreglo
void printArray(int arr[], int size) {
for (int i = 0; i < size; i++)
printf("%d ", arr[i]);
printf("
");
}
int main() {
// Arreglo de ejemplo
int arr[] = {10, 7, 8, 9, 1, 5};
int n = sizeof(arr) / sizeof(arr[0]);
printf("Arreglo original: ");
printArray(arr, n);
// Ejecutar QuickSort
quickSort(arr, 0, n - 1);
printf("Arreglo ordenado: ");
printArray(arr, n);
return 0;
}
#include <iostream>
#include <vector>
// Función para particionar el arreglo
int partition(std::vector<int>& arr, int low, int high) {
// Seleccionar el último elemento como pivote
int pivot = arr[high];
// Índice del elemento más pequeño
int i = low - 1;
// Recorrer todos los elementos del subarreglo
for (int j = low; j < high; j++) {
// Si el elemento actual es menor o igual al pivote
if (arr[j] <= pivot) {
// Incrementar índice de elementos pequeños
i++;
// Intercambiar elementos
std::swap(arr[i], arr[j]);
}
}
// Colocar pivote en posición correcta
std::swap(arr[i + 1], arr[high]);
// Devolver índice del pivote
return i + 1;
}
// Función QuickSort recursiva
void quickSort(std::vector<int>& arr, int low, int high) {
// Verificar si hay más de un elemento para ordenar
if (low < high) {
// 1. DIVIDIR: Particionar el arreglo y obtener el índice del pivote
int pivotIndex = partition(arr, low, high);
// 2. CONQUISTAR: Ordenar recursivamente las sublistas
// Ordenar sublista izquierda (menores que pivote)
quickSort(arr, low, pivotIndex - 1);
// Ordenar sublista derecha (mayores que pivote)
quickSort(arr, pivotIndex + 1, high);
}
}
// Función para imprimir arreglo
void printArray(const std::vector<int>& arr) {
for (int num : arr) {
std::cout << num << " ";
}
std::cout << std::endl;
}
int main() {
// Arreglo de ejemplo
std::vector<int> arr = {10, 7, 8, 9, 1, 5};
std::cout << "Arreglo original: ";
printArray(arr);
// Ejecutar QuickSort
quickSort(arr, 0, arr.size() - 1);
std::cout << "Arreglo ordenado: ";
printArray(arr);
return 0;
}
using System;
class QuickSort {
// Función para particionar el arreglo
static int Partition(int[] arr, int low, int high) {
// Seleccionar el último elemento como pivote
int pivot = arr[high];
// Índice del elemento más pequeño
int i = low - 1;
// Recorrer todos los elementos del subarreglo
for (int j = low; j < high; j++) {
// Si el elemento actual es menor o igual al pivote
if (arr[j] <= pivot) {
// Incrementar índice de elementos pequeños
i++;
// Intercambiar elementos
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
// Colocar pivote en posición correcta
int tempPivot = arr[i + 1];
arr[i + 1] = arr[high];
arr[high] = tempPivot;
// Devolver índice del pivote
return i + 1;
}
// Función QuickSort recursiva
static void QuickSortMethod(int[] arr, int low, int high) {
// Verificar si hay más de un elemento para ordenar
if (low < high) {
// 1. DIVIDIR: Particionar el arreglo y obtener el índice del pivote
int pivotIndex = Partition(arr, low, high);
// 2. CONQUISTAR: Ordenar recursivamente las sublistas
// Ordenar sublista izquierda (menores que pivote)
QuickSortMethod(arr, low, pivotIndex - 1);
// Ordenar sublista derecha (mayores que pivote)
QuickSortMethod(arr, pivotIndex + 1, high);
}
}
// Función para imprimir arreglo
static void PrintArray(int[] arr) {
foreach (int num in arr) {
Console.Write(num + " ");
}
Console.WriteLine();
}
static void Main() {
// Arreglo de ejemplo
int[] arr = {10, 7, 8, 9, 1, 5};
Console.WriteLine("Arreglo original:");
PrintArray(arr);
// Ejecutar QuickSort
QuickSortMethod(arr, 0, arr.Length - 1);
Console.WriteLine("Arreglo ordenado:");
PrintArray(arr);
}
}
Ordenamiento por Montón
Heap Sort es un algoritmo de ordenamiento por comparación que utiliza la estructura de datos Heap (montículo) para ordenar el arreglo. Primero construye un heap máximo a partir del arreglo, y luego extrae el elemento máximo (la raíz) repetidamente, reestructurando el heap en cada iteración.
Complejidad
- Complejidad Temporal:
O(n log n) mejor, promedio y peor caso
- Complejidad Espacial:
O(1) en el lugar
Implementación
/* HeapSort en Java */
// Este algoritmo utiliza un heap máximo para ordenar el arreglo.
public class HeapSort {
// Método para ajustar el subárbol con raíz en 'i'
public static void heapify(int arr[], int n, int i) {
int largest = i; // Inicializa 'largest' como raíz
int left = 2 * i + 1; // Índice del hijo izquierdo
int right = 2 * i + 2; // Índice del hijo derecho
// Si el hijo izquierdo es mayor que la raíz
if (left < n && arr[left] > arr[largest])
largest = left;
// Si el hijo derecho es mayor que el mayor actual
if (right < n && arr[right] > arr[largest])
largest = right;
// Si el mayor no es la raíz
if (largest != i) {
int swap = arr[i];
arr[i] = arr[largest];
arr[largest] = swap;
// Heapifica recursivamente el subárbol afectado
heapify(arr, n, largest);
}
}
// Método principal para realizar HeapSort
public static void heapSort(int arr[]) {
int n = arr.length;
// Construir el heap máximo
for (int i = n / 2 - 1; i >= 0; i--)
heapify(arr, n, i);
// Extraer elementos del heap uno a uno
for (int i = n - 1; i >= 0; i--) {
// Mueve la raíz actual al final
int temp = arr[0];
arr[0] = arr[i];
arr[i] = temp;
// Heapifica el heap reducido
heapify(arr, i, 0);
}
}
public static void main(String args[]) {
int arr[] = { 12, 11, 13, 5, 6, 7 };
System.out.println("Array original:");
for (int num : arr)
System.out.print(num + " ");
System.out.println();
heapSort(arr);
System.out.println("Array ordenado:");
for (int num : arr)
System.out.print(num + " ");
}
}
# HeapSort en Python
def heapify(arr, n, i):
# Inicializa 'largest' como raíz
largest = i
left = 2 * i + 1 # Hijo izquierdo
right = 2 * i + 2 # Hijo derecho
# Si el hijo izquierdo es mayor que la raíz
if left < n and arr[left] > arr[largest]:
largest = left
# Si el hijo derecho es mayor que el mayor actual
if right < n and arr[right] > arr[largest]:
largest = right
# Si el mayor no es la raíz, se intercambian y se heapifica recursivamente
if largest != i:
arr[i], arr[largest] = arr[largest], arr[i]
heapify(arr, n, largest)
def heapSort(arr):
n = len(arr)
# Construir el heap máximo
for i in range(n // 2 - 1, -1, -1):
heapify(arr, n, i)
# Extraer elementos uno a uno
for i in range(n - 1, 0, -1):
arr[0], arr[i] = arr[i], arr[0] # Intercambio
heapify(arr, i, 0)
# Ejemplo de uso
if __name__ == "__main__":
arr = [12, 11, 13, 5, 6, 7]
print("Array original:", arr)
heapSort(arr)
print("Array ordenado:", arr)
/* HeapSort en JavaScript */
// Utiliza un heap máximo para ordenar el arreglo.
function heapify(arr, n, i) {
let largest = i; // Inicializa 'largest' como raíz
let left = 2 * i + 1; // Índice del hijo izquierdo
let right = 2 * i + 2; // Índice del hijo derecho
// Si el hijo izquierdo es mayor que la raíz
if (left < n && arr[left] > arr[largest])
largest = left;
// Si el hijo derecho es mayor que el mayor actual
if (right < n && arr[right] > arr[largest])
largest = right;
// Si 'largest' no es la raíz, se realiza el intercambio y se heapifica
if (largest !== i) {
[arr[i], arr[largest]] = [arr[largest], arr[i]];
heapify(arr, n, largest);
}
}
function heapSort(arr) {
let n = arr.length;
// Construir el heap máximo
for (let i = Math.floor(n / 2) - 1; i >= 0; i--) {
heapify(arr, n, i);
}
// Extraer elementos uno a uno
for (let i = n - 1; i > 0; i--) {
[arr[0], arr[i]] = [arr[i], arr[0]];
heapify(arr, i, 0);
}
return arr;
}
// Ejemplo de uso:
let arr = [12, 11, 13, 5, 6, 7];
console.log("Array original:", arr);
console.log("Array ordenado:", heapSort(arr));
/* HeapSort en TypeScript */
function heapify(arr: number[], n: number, i: number): void {
let largest: number = i; // Inicializa 'largest' como raíz
let left: number = 2 * i + 1; // Índice del hijo izquierdo
let right: number = 2 * i + 2; // Índice del hijo derecho
// Comprueba si el hijo izquierdo es mayor que la raíz
if (left < n && arr[left] > arr[largest]) {
largest = left;
}
// Comprueba si el hijo derecho es mayor que el mayor actual
if (right < n && arr[right] > arr[largest]) {
largest = right;
}
// Si 'largest' no es la raíz, se intercambian los elementos y se llama recursivamente a heapify
if (largest !== i) {
[arr[i], arr[largest]] = [arr[largest], arr[i]];
heapify(arr, n, largest);
}
}
function heapSort(arr: number[]): number[] {
const n: number = arr.length;
// Construir el heap máximo
for (let i = Math.floor(n / 2) - 1; i >= 0; i--) {
heapify(arr, n, i);
}
// Extraer elementos uno a uno
for (let i = n - 1; i > 0; i--) {
[arr[0], arr[i]] = [arr[i], arr[0]];
heapify(arr, i, 0);
}
return arr;
}
// Ejemplo de uso:
const arr: number[] = [12, 11, 13, 5, 6, 7];
console.log("Array original:", arr);
console.log("Array ordenado:", heapSort(arr));
/* HeapSort en Go */
package main
import "fmt"
// Función heapify ajusta el subárbol con raíz en 'i'
func heapify(arr []int, n int, i int) {
largest := i // Inicializa 'largest' como raíz
left := 2*i + 1 // Hijo izquierdo
right := 2*i + 2 // Hijo derecho
// Si el hijo izquierdo es mayor que la raíz
if left < n && arr[left] > arr[largest] {
largest = left
}
// Si el hijo derecho es mayor que el mayor actual
if right < n && arr[right] > arr[largest] {
largest = right
}
// Si 'largest' no es la raíz, intercambia y heapifica recursivamente
if largest != i {
arr[i], arr[largest] = arr[largest], arr[i]
heapify(arr, n, largest)
}
}
// Función heapSort que ordena el arreglo usando HeapSort
func heapSort(arr []int) {
n := len(arr)
// Construir el heap máximo
for i := n/2 - 1; i >= 0; i-- {
heapify(arr, n, i)
}
// Extraer elementos uno a uno del heap
for i := n - 1; i >= 0; i-- {
arr[0], arr[i] = arr[i], arr[0]
heapify(arr, i, 0)
}
}
func main() {
arr := []int{12, 11, 13, 5, 6, 7}
fmt.Println("Array original:", arr)
heapSort(arr)
fmt.Println("Array ordenado:", arr)
}
/* HeapSort en C */
#include <stdio.h>
// Función para intercambiar dos elementos
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
// Heapify ajusta el subárbol con raíz en 'i'
void heapify(int arr[], int n, int i) {
int largest = i; // Inicializa 'largest' como raíz
int left = 2 * i + 1; // Hijo izquierdo
int right = 2 * i + 2; // Hijo derecho
if (left < n && arr[left] > arr[largest])
largest = left;
if (right < n && arr[right] > arr[largest])
largest = right;
if (largest != i) {
swap(&arr[i], &arr[largest]);
heapify(arr, n, largest);
}
}
// Función principal de HeapSort
void heapSort(int arr[], int n) {
// Construir el heap máximo
for (int i = n / 2 - 1; i >= 0; i--)
heapify(arr, n, i);
// Extraer elementos uno a uno
for (int i = n - 1; i >= 0; i--) {
swap(&arr[0], &arr[i]);
heapify(arr, i, 0);
}
}
int main() {
int arr[] = {12, 11, 13, 5, 6, 7};
int n = sizeof(arr)/sizeof(arr[0]);
printf("Array original: ");
for (int i = 0; i < n; i++)
printf("%d ", arr[i]);
printf("
");
heapSort(arr, n);
printf("Array ordenado: ");
for (int i = 0; i < n; i++)
printf("%d ", arr[i]);
printf("
");
return 0;
}
/* HeapSort en C++ */
#include <iostream>
#include <vector>
using namespace std;
// Función heapify que ajusta el subárbol con raíz en 'i'
void heapify(vector<int>& arr, int n, int i) {
int largest = i; // Inicializa 'largest' como raíz
int left = 2 * i + 1; // Hijo izquierdo
int right = 2 * i + 2; // Hijo derecho
if (left < n && arr[left] > arr[largest])
largest = left;
if (right < n && arr[right] > arr[largest])
largest = right;
if (largest != i) {
swap(arr[i], arr[largest]); // Intercambio
heapify(arr, n, largest);
}
}
// Función principal de HeapSort
void heapSort(vector<int>& arr) {
int n = arr.size();
for (int i = n / 2 - 1; i >= 0; i--)
heapify(arr, n, i);
for (int i = n - 1; i >= 0; i--) {
swap(arr[0], arr[i]);
heapify(arr, i, 0);
}
}
int main() {
vector<int> arr = {12, 11, 13, 5, 6, 7};
cout << "Array original: ";
for (int num : arr)
cout << num << " ";
cout << endl;
heapSort(arr);
cout << "Array ordenado: ";
for (int num : arr)
cout << num << " ";
cout << endl;
return 0;
}
/* HeapSort en C# */
using System;
public class HeapSortClass {
// Método para heapificar el subárbol con raíz en 'i'
public static void Heapify(int[] arr, int n, int i) {
int largest = i; // Inicializa 'largest' como raíz
int left = 2 * i + 1; // Hijo izquierdo
int right = 2 * i + 2; // Hijo derecho
if (left < n && arr[left] > arr[largest])
largest = left;
if (right < n && arr[right] > arr[largest])
largest = right;
if (largest != i) {
int temp = arr[i];
arr[i] = arr[largest];
arr[largest] = temp;
Heapify(arr, n, largest);
}
}
// Método principal para HeapSort
public static void HeapSort(int[] arr) {
int n = arr.Length;
for (int i = n / 2 - 1; i >= 0; i--)
Heapify(arr, n, i);
for (int i = n - 1; i >= 0; i--) {
int temp = arr[0];
arr[0] = arr[i];
arr[i] = temp;
Heapify(arr, i, 0);
}
}
public static void Main() {
int[] arr = {12, 11, 13, 5, 6, 7};
Console.WriteLine("Array original: " + string.Join(" ", arr));
HeapSort(arr);
Console.WriteLine("Array ordenado: " + string.Join(" ", arr));
}
}
Ordenamiento por Cubos
El ordenamiento por cubos (BucketSort) divide el arreglo en un número finito de “cubos” o buckets. Cada bucket se ordena individualmente (usualmente mediante otro algoritmo de ordenamiento) y luego se concatenan para obtener el arreglo final ordenado. Es ideal para datos distribuidos uniformemente en un rango conocido (usualmente [0,1)). En las implementaciones se asume que los valores están en el rango [0,1).
Complejidad
- Complejidad Temporal:
O(n + k) promedio y mejor caso, O(n²) peor caso
- Complejidad Espacial:
O(n)
Implementación
/* Bucket Sort en Java */
// Este algoritmo distribuye los elementos en 'n' buckets y luego ordena cada uno.
import java.util.ArrayList;
import java.util.Collections;
public class BucketSort {
public static void bucketSort(float[] arr) {
int n = arr.length;
if (n <= 0)
return;
// Crear 'n' buckets
ArrayList<Float>[] buckets = new ArrayList[n];
for (int i = 0; i < n; i++) {
buckets[i] = new ArrayList<Float>();
}
// Distribuir los elementos en sus respectivos buckets
for (int i = 0; i < n; i++) {
int bucketIndex = (int)(n * arr[i]);
buckets[bucketIndex].add(arr[i]);
}
// Ordenar cada bucket y concatenar
int index = 0;
for (int i = 0; i < n; i++) {
Collections.sort(buckets[i]);
for (float value : buckets[i]) {
arr[index++] = value;
}
}
}
public static void main(String[] args) {
float[] arr = {0.42f, 0.32f, 0.33f, 0.52f, 0.25f, 0.47f, 0.51f};
System.out.println("Array original:");
for (float num : arr) {
System.out.print(num + " ");
}
System.out.println();
bucketSort(arr);
System.out.println("Array ordenado:");
for (float num : arr) {
System.out.print(num + " ");
}
}
}
# Bucket Sort en Python
def bucketSort(arr):
n = len(arr)
if n <= 0:
return arr
# Crear n buckets
buckets = [[] for _ in range(n)]
# Insertar cada elemento en su bucket correspondiente
for num in arr:
index = int(n * num)
buckets[index].append(num)
# Ordenar cada bucket y concatenar los resultados
sorted_arr = []
for bucket in buckets:
sorted_arr.extend(sorted(bucket))
return sorted_arr
if __name__ == "__main__":
arr = [0.42, 0.32, 0.33, 0.52, 0.25, 0.47, 0.51]
print("Array original:", arr)
sorted_arr = bucketSort(arr)
print("Array ordenado:", sorted_arr)
/* Bucket Sort en JavaScript */
// Distribuye los elementos en buckets y ordena cada bucket.
function bucketSort(arr) {
const n = arr.length;
if (n <= 0) return arr;
// Crear buckets
let buckets = Array.from({ length: n }, () => []);
// Distribuir elementos en buckets
for (let i = 0; i < n; i++) {
let index = Math.floor(n * arr[i]);
buckets[index].push(arr[i]);
}
// Ordenar cada bucket y concatenar los resultados
let sortedArr = [];
for (let bucket of buckets) {
bucket.sort((a, b) => a - b);
sortedArr = sortedArr.concat(bucket);
}
return sortedArr;
}
// Ejemplo de uso:
let arr = [0.42, 0.32, 0.33, 0.52, 0.25, 0.47, 0.51];
console.log("Array original:", arr);
console.log("Array ordenado:", bucketSort(arr));
/* Bucket Sort en TypeScript */
function bucketSort(arr: number[]): number[] {
const n: number = arr.length;
if (n <= 0) return arr;
// Crear buckets
let buckets: number[][] = Array.from({ length: n }, () => []);
// Distribuir los elementos en sus respectivos buckets
for (let i = 0; i < n; i++) {
let index: number = Math.floor(n * arr[i]);
buckets[index].push(arr[i]);
}
// Ordenar cada bucket y concatenar los resultados
let sortedArr: number[] = [];
for (let bucket of buckets) {
bucket.sort((a, b) => a - b);
sortedArr = sortedArr.concat(bucket);
}
return sortedArr;
}
// Ejemplo de uso:
const arr: number[] = [0.42, 0.32, 0.33, 0.52, 0.25, 0.47, 0.51];
console.log("Array original:", arr);
console.log("Array ordenado:", bucketSort(arr));
/* Bucket Sort en Go */
package main
import (
"fmt"
"sort"
)
// bucketSort ordena un slice de float64 usando Bucket Sort
func bucketSort(arr []float64) {
n := len(arr)
if n <= 0 {
return
}
// Crear n buckets
buckets := make([][]float64, n)
for i := range buckets {
buckets[i] = []float64{}
}
// Distribuir elementos en buckets
for i := 0; i < n; i++ {
index := int(float64(n) * arr[i])
buckets[index] = append(buckets[index], arr[i])
}
// Ordenar cada bucket y concatenar resultados
idx := 0
for i := 0; i < n; i++ {
sort.Float64s(buckets[i])
for _, num := range buckets[i] {
arr[idx] = num
idx++
}
}
}
func main() {
arr := []float64{0.42, 0.32, 0.33, 0.52, 0.25, 0.47, 0.51}
fmt.Println("Array original:", arr)
bucketSort(arr)
fmt.Println("Array ordenado:", arr)
}
/* Bucket Sort en C (para números en el rango [0,1)) */
#include <stdio.h>
#include <stdlib.h>
// Función de comparación para qsort
int compare(const void *a, const void *b) {
float fa = *(const float*)a;
float fb = *(const float*)b;
return (fa > fb) - (fa < fb);
}
// Bucket Sort para un arreglo de floats
void bucketSort(float arr[], int n) {
int bucketCount = n;
// Crear array de buckets
float** buckets = (float**)malloc(bucketCount * sizeof(float*));
int* bucketSizes = (int*)calloc(bucketCount, sizeof(int));
int* bucketCapacities = (int*)malloc(bucketCount * sizeof(int));
// Inicializar cada bucket
for (int i = 0; i < bucketCount; i++) {
bucketCapacities[i] = 5; // capacidad inicial
buckets[i] = (float*)malloc(bucketCapacities[i] * sizeof(float));
}
// Distribuir elementos en buckets
for (int i = 0; i < n; i++) {
int index = (int)(arr[i] * bucketCount);
if (bucketSizes[index] == bucketCapacities[index]) {
bucketCapacities[index] *= 2;
buckets[index] = (float*)realloc(buckets[index], bucketCapacities[index] * sizeof(float));
}
buckets[index][bucketSizes[index]++] = arr[i];
}
// Ordenar cada bucket y copiar al arreglo original
int idx = 0;
for (int i = 0; i < bucketCount; i++) {
if (bucketSizes[i] > 0) {
qsort(buckets[i], bucketSizes[i], sizeof(float), compare);
for (int j = 0; j < bucketSizes[i]; j++) {
arr[idx++] = buckets[i][j];
}
}
free(buckets[i]);
}
free(buckets);
free(bucketSizes);
free(bucketCapacities);
}
int main() {
float arr[] = {0.42, 0.32, 0.33, 0.52, 0.25, 0.47, 0.51};
int n = sizeof(arr)/sizeof(arr[0]);
printf("Array original: ");
for (int i = 0; i < n; i++) {
printf("%.2f ", arr[i]);
}
printf("
");
bucketSort(arr, n);
printf("Array ordenado: ");
for (int i = 0; i < n; i++) {
printf("%.2f ", arr[i]);
}
printf("
");
return 0;
}
/* Bucket Sort en C++ (para números en el rango [0,1)) */
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
void bucketSort(vector<float>& arr) {
int n = arr.size();
vector<vector<float>> buckets(n);
// Distribuir cada elemento en su bucket
for (int i = 0; i < n; i++) {
int index = n * arr[i];
buckets[index].push_back(arr[i]);
}
// Ordenar cada bucket y concatenar los resultados
arr.clear();
for (int i = 0; i < n; i++) {
sort(buckets[i].begin(), buckets[i].end());
for (float num : buckets[i]) {
arr.push_back(num);
}
}
}
int main() {
vector<float> arr = {0.42, 0.32, 0.33, 0.52, 0.25, 0.47, 0.51};
cout << "Array original: ";
for (float num : arr)
cout << num << " ";
cout << endl;
bucketSort(arr);
cout << "Array ordenado: ";
for (float num : arr)
cout << num << " ";
cout << endl;
return 0;
}
/* Bucket Sort en C# (para números en el rango [0,1)) */
using System;
using System.Collections.Generic;
public class BucketSortClass {
public static void BucketSort(float[] arr) {
int n = arr.Length;
if (n <= 0) return;
// Crear buckets
List<float>[] buckets = new List<float>[n];
for (int i = 0; i < n; i++) {
buckets[i] = new List<float>();
}
// Distribuir cada elemento en su bucket
for (int i = 0; i < n; i++) {
int index = (int)(arr[i] * n);
buckets[index].Add(arr[i]);
}
// Ordenar cada bucket y copiar de vuelta al arreglo
int idx = 0;
for (int i = 0; i < n; i++) {
buckets[i].Sort();
foreach (float num in buckets[i]) {
arr[idx++] = num;
}
}
}
public static void Main() {
float[] arr = {0.42f, 0.32f, 0.33f, 0.52f, 0.25f, 0.47f, 0.51f};
Console.WriteLine("Array original: " + string.Join(" ", arr));
BucketSort(arr);
Console.WriteLine("Array ordenado: " + string.Join(" ", arr));
}
}
Ordenamiento por Base
El ordenamiento por base (RadixSort) es un algoritmo de ordenamiento no comparativo que ordena enteros procesando los dígitos individuales. Se basa en el principio de ordenar los dígitos menos significativos primero, y luego los más significativos. RadixSort puede ser de tipo LSD (Least Significant Digit) o MSD (Most Significant Digit).
Complejidad
- Complejidad Temporal:
O(nk) mejor, promedio y peor caso
- Complejidad Espacial:
O(n + k)
Implementación
/* Radix Sort en Java */
// Este algoritmo utiliza Count Sort de forma repetida para cada dígito.
public class RadixSort {
// Encuentra el valor máximo en el arreglo
public static int getMax(int arr[]) {
int max = arr[0];
for (int i = 1; i < arr.length; i++)
if (arr[i] > max)
max = arr[i];
return max;
}
// Count Sort aplicado según el dígito representado por 'exp'
public static void countSort(int arr[], int exp) {
int n = arr.length;
int output[] = new int[n];
int count[] = new int[10];
// Contar las ocurrencias del dígito
for (int i = 0; i < n; i++)
count[(arr[i] / exp) % 10]++;
// Actualizar count para posiciones acumuladas
for (int i = 1; i < 10; i++)
count[i] += count[i - 1];
// Construir el arreglo de salida
for (int i = n - 1; i >= 0; i--) {
output[count[(arr[i] / exp) % 10] - 1] = arr[i];
count[(arr[i] / exp) % 10]--;
}
// Copiar el arreglo de salida a arr[]
for (int i = 0; i < n; i++)
arr[i] = output[i];
}
// Función principal de RadixSort
public static void radixSort(int arr[]) {
int m = getMax(arr);
// Aplicar Count Sort para cada dígito
for (int exp = 1; m / exp > 0; exp *= 10)
countSort(arr, exp);
}
public static void main(String args[]) {
int arr[] = {170, 45, 75, 90, 802, 24, 2, 66};
System.out.println("Array original:");
for (int num : arr)
System.out.print(num + " ");
System.out.println();
radixSort(arr);
System.out.println("Array ordenado:");
for (int num : arr)
System.out.print(num + " ");
}
}
# Radix Sort en Python
def countingSort(arr, exp):
n = len(arr)
output = [0] * n
count = [0] * 10
# Contar ocurrencias del dígito en 'exp'
for i in range(n):
index = (arr[i] // exp) % 10
count[index] += 1
# Actualizar count para posiciones acumuladas
for i in range(1, 10):
count[i] += count[i - 1]
# Construir el arreglo de salida
i = n - 1
while i >= 0:
index = (arr[i] // exp) % 10
output[count[index] - 1] = arr[i]
count[index] -= 1
i -= 1
# Copiar el arreglo de salida a arr
for i in range(n):
arr[i] = output[i]
def radixSort(arr):
max_val = max(arr)
exp = 1
while max_val // exp > 0:
countingSort(arr, exp)
exp *= 10
if __name__ == "__main__":
arr = [170, 45, 75, 90, 802, 24, 2, 66]
print("Array original:", arr)
radixSort(arr)
print("Array ordenado:", arr)
/* Radix Sort en JavaScript */
// Utiliza Count Sort para cada dígito.
function countingSort(arr, exp) {
let n = arr.length;
let output = new Array(n).fill(0);
let count = new Array(10).fill(0);
// Contar ocurrencias del dígito actual
for (let i = 0; i < n; i++) {
let index = Math.floor(arr[i] / exp) % 10;
count[index]++;
}
// Actualizar count para posiciones acumuladas
for (let i = 1; i < 10; i++) {
count[i] += count[i - 1];
}
// Construir el arreglo de salida
for (let i = n - 1; i >= 0; i--) {
let index = Math.floor(arr[i] / exp) % 10;
output[count[index] - 1] = arr[i];
count[index]--;
}
// Copiar el arreglo de salida a arr
for (let i = 0; i < n; i++) {
arr[i] = output[i];
}
}
function radixSort(arr) {
let maxVal = Math.max(...arr);
for (let exp = 1; Math.floor(maxVal / exp) > 0; exp *= 10) {
countingSort(arr, exp);
}
return arr;
}
// Ejemplo de uso:
let arr = [170, 45, 75, 90, 802, 24, 2, 66];
console.log("Array original:", arr);
console.log("Array ordenado:", radixSort(arr));
/* Radix Sort en TypeScript */
function countingSort(arr: number[], exp: number): void {
const n: number = arr.length;
let output: number[] = new Array(n).fill(0);
let count: number[] = new Array(10).fill(0);
// Contar ocurrencias del dígito
for (let i = 0; i < n; i++) {
let index: number = Math.floor(arr[i] / exp) % 10;
count[index]++;
}
// Actualizar count para posiciones acumuladas
for (let i = 1; i < 10; i++) {
count[i] += count[i - 1];
}
// Construir el arreglo de salida
for (let i = n - 1; i >= 0; i--) {
let index: number = Math.floor(arr[i] / exp) % 10;
output[count[index] - 1] = arr[i];
count[index]--;
}
// Copiar el arreglo de salida a arr
for (let i = 0; i < n; i++) {
arr[i] = output[i];
}
}
function radixSort(arr: number[]): number[] {
let maxVal: number = Math.max(...arr);
for (let exp: number = 1; Math.floor(maxVal / exp) > 0; exp *= 10) {
countingSort(arr, exp);
}
return arr;
}
// Ejemplo de uso:
const arr: number[] = [170, 45, 75, 90, 802, 24, 2, 66];
console.log("Array original:", arr);
console.log("Array ordenado:", radixSort(arr));
/* Radix Sort en Go */
package main
import (
"fmt"
)
// Función countingSort usada por radixSort
func countingSort(arr []int, exp int) {
n := len(arr)
output := make([]int, n)
count := make([]int, 10)
// Contar ocurrencias de dígitos
for i := 0; i < n; i++ {
index := (arr[i] / exp) % 10
count[index]++
}
// Actualizar count
for i := 1; i < 10; i++ {
count[i] += count[i-1]
}
// Construir el arreglo de salida
for i := n - 1; i >= 0; i-- {
index := (arr[i] / exp) % 10
output[count[index]-1] = arr[i]
count[index]--
}
// Copiar salida en arr
for i := 0; i < n; i++ {
arr[i] = output[i]
}
}
func radixSort(arr []int) {
maxVal := arr[0]
for i := 1; i < len(arr); i++ {
if arr[i] > maxVal {
maxVal = arr[i]
}
}
exp := 1
for maxVal/exp > 0 {
countingSort(arr, exp)
exp *= 10
}
}
func main() {
arr := []int{170, 45, 75, 90, 802, 24, 2, 66}
fmt.Println("Array original:", arr)
radixSort(arr)
fmt.Println("Array ordenado:", arr)
}
/* Radix Sort en C */
#include <stdio.h>
#include <stdlib.h>
// Función para obtener el máximo del arreglo
int getMax(int arr[], int n) {
int max = arr[0];
for (int i = 1; i < n; i++)
if (arr[i] > max)
max = arr[i];
return max;
}
// Count Sort basado en el dígito representado por 'exp'
void countSort(int arr[], int n, int exp) {
int *output = (int*)malloc(n * sizeof(int));
int count[10] = {0};
// Contar ocurrencias
for (int i = 0; i < n; i++)
count[(arr[i] / exp) % 10]++;
// Actualizar count
for (int i = 1; i < 10; i++)
count[i] += count[i - 1];
// Construir el arreglo de salida
for (int i = n - 1; i >= 0; i--) {
output[count[(arr[i] / exp) % 10] - 1] = arr[i];
count[(arr[i] / exp) % 10]--;
}
// Copiar el arreglo de salida a arr[]
for (int i = 0; i < n; i++)
arr[i] = output[i];
free(output);
}
void radixSort(int arr[], int n) {
int m = getMax(arr, n);
// Aplicar Count Sort para cada dígito
for (int exp = 1; m / exp > 0; exp *= 10)
countSort(arr, n, exp);
}
int main() {
int arr[] = {170, 45, 75, 90, 802, 24, 2, 66};
int n = sizeof(arr)/sizeof(arr[0]);
printf("Array original: ");
for (int i = 0; i < n; i++)
printf("%d ", arr[i]);
printf("
");
radixSort(arr, n);
printf("Array ordenado: ");
for (int i = 0; i < n; i++)
printf("%d ", arr[i]);
printf("
");
return 0;
}
/* Radix Sort en C++ */
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int getMax(const vector<int>& arr) {
int mx = arr[0];
for (int i = 1; i < arr.size(); i++)
mx = max(mx, arr[i]);
return mx;
}
void countSort(vector<int>& arr, int exp) {
int n = arr.size();
vector<int> output(n);
vector<int> count(10, 0);
// Contar ocurrencias del dígito
for (int i = 0; i < n; i++)
count[(arr[i] / exp) % 10]++;
// Actualizar count
for (int i = 1; i < 10; i++)
count[i] += count[i - 1];
// Construir el arreglo de salida
for (int i = n - 1; i >= 0; i--) {
output[count[(arr[i] / exp) % 10] - 1] = arr[i];
count[(arr[i] / exp) % 10]--;
}
// Copiar salida en arr
for (int i = 0; i < n; i++)
arr[i] = output[i];
}
void radixSort(vector<int>& arr) {
int m = getMax(arr);
for (int exp = 1; m/exp > 0; exp *= 10)
countSort(arr, exp);
}
int main() {
vector<int> arr = {170, 45, 75, 90, 802, 24, 2, 66};
cout << "Array original: ";
for (int num : arr)
cout << num << " ";
cout << endl;
radixSort(arr);
cout << "Array ordenado: ";
for (int num : arr)
cout << num << " ";
cout << endl;
return 0;
}
/* Radix Sort en C# */
using System;
public class RadixSortClass {
// Función para obtener el máximo del arreglo
public static int GetMax(int[] arr) {
int max = arr[0];
for (int i = 1; i < arr.Length; i++)
if (arr[i] > max)
max = arr[i];
return max;
}
// Count Sort basado en el dígito representado por 'exp'
public static void CountSort(int[] arr, int exp) {
int n = arr.Length;
int[] output = new int[n];
int[] count = new int[10];
// Contar ocurrencias del dígito
for (int i = 0; i < n; i++)
count[(arr[i] / exp) % 10]++;
// Actualizar count
for (int i = 1; i < 10; i++)
count[i] += count[i - 1];
// Construir el arreglo de salida
for (int i = n - 1; i >= 0; i--) {
output[count[(arr[i] / exp) % 10] - 1] = arr[i];
count[(arr[i] / exp) % 10]--;
}
// Copiar el arreglo de salida a arr
for (int i = 0; i < n; i++)
arr[i] = output[i];
}
public static void RadixSort(int[] arr) {
int m = GetMax(arr);
for (int exp = 1; m/exp > 0; exp *= 10)
CountSort(arr, exp);
}
public static void Main() {
int[] arr = {170, 45, 75, 90, 802, 24, 2, 66};
Console.WriteLine("Array original: " + string.Join(" ", arr));
RadixSort(arr);
Console.WriteLine("Array ordenado: " + string.Join(" ", arr));
}
}
Ordenamiento de Tim
El ordenamiento de Tim (Timsort) es un algoritmo híbrido derivado de MergeSort y InsertionSort. Fue diseñado para aprovechar las ventajas de ambos algoritmos en arreglos de datos reales. Timsort es el algoritmo de ordenamiento predeterminado en Python y Java.
Complejidad
- Complejidad Temporal:
O(n) mejor caso, O(n log n) promedio y peor caso
- Complejidad Espacial:
O(n)
Implementación
/* TimSort en Java */
// Implementación simplificada de TimSort: se utiliza Insertion Sort en runs y luego se fusionan.
public class TimSort {
static int MIN_RUN = 32;
// Insertion Sort para ordenar un subarreglo de 'left' a 'right'
public static void insertionSort(int[] arr, int left, int right) {
for (int i = left + 1; i <= right; i++) {
int temp = arr[i];
int j = i - 1;
while (j >= left && arr[j] > temp) {
arr[j+1] = arr[j];
j--;
}
arr[j+1] = temp;
}
}
// Fusiona dos subarreglos: arr[l...m] y arr[m+1...r]
public static void merge(int[] arr, int l, int m, int r) {
int len1 = m - l + 1, len2 = r - m;
int[] left = new int[len1];
int[] right = new int[len2];
for (int x = 0; x < len1; x++)
left[x] = arr[l + x];
for (int x = 0; x < len2; x++)
right[x] = arr[m + 1 + x];
int i = 0, j = 0, k = l;
while (i < len1 && j < len2) {
if (left[i] <= right[j])
arr[k++] = left[i++];
else
arr[k++] = right[j++];
}
while (i < len1)
arr[k++] = left[i++];
while (j < len2)
arr[k++] = right[j++];
}
// Función principal de TimSort
public static void timSort(int[] arr) {
int n = arr.length;
// Ordenar pequeños segmentos con Insertion Sort
for (int i = 0; i < n; i += MIN_RUN) {
insertionSort(arr, i, Math.min(i + MIN_RUN - 1, n - 1));
}
// Fusionar runs de tamaño 'minRun'
for (int size = MIN_RUN; size < n; size = 2 * size) {
for (int left = 0; left < n; left += 2 * size) {
int mid = left + size - 1;
int right = Math.min(left + 2 * size - 1, n - 1);
if (mid < right)
merge(arr, left, mid, right);
}
}
}
public static void main(String[] args) {
int[] arr = {5, 21, 7, 23, 19, 10, 3, 15, 1, 9};
System.out.println("Array original:");
for (int num : arr)
System.out.print(num + " ");
System.out.println();
timSort(arr);
System.out.println("Array ordenado:");
for (int num : arr)
System.out.print(num + " ");
}
}
# TimSort en Python (versión simplificada)
def insertionSort(arr, left, right):
for i in range(left+1, right+1):
key = arr[i]
j = i - 1
while j >= left and arr[j] > key:
arr[j+1] = arr[j]
j -= 1
arr[j+1] = key
def merge(arr, l, m, r):
left = arr[l:m+1]
right = arr[m+1:r+1]
i = j = 0
k = l
while i < len(left) and j < len(right):
if left[i] <= right[j]:
arr[k] = left[i]
i += 1
else:
arr[k] = right[j]
j += 1
k += 1
while i < len(left):
arr[k] = left[i]
i += 1; k += 1
while j < len(right):
arr[k] = right[j]
j += 1; k += 1
def timSort(arr):
n = len(arr)
minRun = 32
# Ordenar cada segmento pequeño usando Insertion Sort
for start in range(0, n, minRun):
end = min(start+minRun-1, n-1)
insertionSort(arr, start, end)
size = minRun
# Fusionar los segmentos ordenados
while size < n:
for left in range(0, n, 2*size):
mid = min(n-1, left+size-1)
right = min((left+2*size-1), n-1)
if mid < right:
merge(arr, left, mid, right)
size *= 2
if __name__ == "__main__":
arr = [5, 21, 7, 23, 19, 10, 3, 15, 1, 9]
print("Array original:", arr)
timSort(arr)
print("Array ordenado:", arr)
/* TimSort en JavaScript (versión simplificada) */
function insertionSort(arr, left, right) {
for (let i = left + 1; i <= right; i++) {
let temp = arr[i];
let j = i - 1;
while (j >= left && arr[j] > temp) {
arr[j+1] = arr[j];
j--;
}
arr[j+1] = temp;
}
}
function merge(arr, l, m, r) {
let left = arr.slice(l, m+1);
let right = arr.slice(m+1, r+1);
let i = 0, j = 0, k = l;
while (i < left.length && j < right.length) {
if (left[i] <= right[j]) {
arr[k++] = left[i++];
} else {
arr[k++] = right[j++];
}
}
while (i < left.length) {
arr[k++] = left[i++];
}
while (j < right.length) {
arr[k++] = right[j++];
}
}
function timSort(arr) {
const MIN_RUN = 32;
let n = arr.length;
// Ordenar segmentos pequeños con Insertion Sort
for (let i = 0; i < n; i += MIN_RUN) {
insertionSort(arr, i, Math.min(i + MIN_RUN - 1, n - 1));
}
// Fusionar los segmentos ordenados
for (let size = MIN_RUN; size < n; size = 2 * size) {
for (let left = 0; left < n; left += 2 * size) {
let mid = left + size - 1;
let right = Math.min(left + 2 * size - 1, n - 1);
if (mid < right) {
merge(arr, left, mid, right);
}
}
}
return arr;
}
// Ejemplo de uso:
let arr = [5, 21, 7, 23, 19, 10, 3, 15, 1, 9];
console.log("Array original:", arr);
console.log("Array ordenado:", timSort(arr));
/* TimSort en TypeScript (versión simplificada) */
function insertionSort(arr: number[], left: number, right: number): void {
for (let i = left + 1; i <= right; i++) {
let temp: number = arr[i];
let j: number = i - 1;
while (j >= left && arr[j] > temp) {
arr[j+1] = arr[j];
j--;
}
arr[j+1] = temp;
}
}
function merge(arr: number[], l: number, m: number, r: number): void {
let left: number[] = arr.slice(l, m+1);
let right: number[] = arr.slice(m+1, r+1);
let i = 0, j = 0, k = l;
while (i < left.length && j < right.length) {
if (left[i] <= right[j]) {
arr[k++] = left[i++];
} else {
arr[k++] = right[j++];
}
}
while (i < left.length) {
arr[k++] = left[i++];
}
while (j < right.length) {
arr[k++] = right[j++];
}
}
function timSort(arr: number[]): number[] {
const MIN_RUN: number = 32;
let n: number = arr.length;
for (let i = 0; i < n; i += MIN_RUN) {
insertionSort(arr, i, Math.min(i + MIN_RUN - 1, n - 1));
}
for (let size = MIN_RUN; size < n; size *= 2) {
for (let left = 0; left < n; left += 2 * size) {
let mid: number = left + size - 1;
let right: number = Math.min(left + 2 * size - 1, n - 1);
if (mid < right) {
merge(arr, left, mid, right);
}
}
}
return arr;
}
// Ejemplo de uso:
const arr: number[] = [5, 21, 7, 23, 19, 10, 3, 15, 1, 9];
console.log("Array original:", arr);
console.log("Array ordenado:", timSort(arr));
/* TimSort en Go (versión simplificada) */
package main
import "fmt"
func insertionSort(arr []int, left, right int) {
for i := left + 1; i <= right; i++ {
temp := arr[i]
j := i - 1
for j >= left && arr[j] > temp {
arr[j+1] = arr[j]
j--
}
arr[j+1] = temp
}
}
func merge(arr []int, l, m, r int) {
leftArr := make([]int, m-l+1)
rightArr := make([]int, r-m)
copy(leftArr, arr[l:m+1])
copy(rightArr, arr[m+1:r+1])
i, j, k := 0, 0, l
for i < len(leftArr) && j < len(rightArr) {
if leftArr[i] <= rightArr[j] {
arr[k] = leftArr[i]
i++
} else {
arr[k] = rightArr[j]
j++
}
k++
}
for i < len(leftArr) {
arr[k] = leftArr[i]
i++; k++
}
for j < len(rightArr) {
arr[k] = rightArr[j]
j++; k++
}
}
func timSort(arr []int) {
n := len(arr)
const MIN_RUN = 32
for i := 0; i < n; i += MIN_RUN {
end := i + MIN_RUN - 1
if end >= n {
end = n - 1
}
insertionSort(arr, i, end)
}
size := MIN_RUN
for size < n {
for left := 0; left < n; left += 2 * size {
mid := left + size - 1
right := left + 2*size - 1
if right >= n {
right = n - 1
}
if mid < right {
merge(arr, left, mid, right)
}
}
size *= 2
}
}
func main() {
arr := []int{5, 21, 7, 23, 19, 10, 3, 15, 1, 9}
fmt.Println("Array original:", arr)
timSort(arr)
fmt.Println("Array ordenado:", arr)
}
/* TimSort en C (versión simplificada) */
#include <stdio.h>
#include <stdlib.h>
#define MIN_RUN 32
// Insertion Sort para un subarreglo de 'left' a 'right'
void insertionSort(int arr[], int left, int right) {
for (int i = left + 1; i <= right; i++) {
int temp = arr[i];
int j = i - 1;
while (j >= left && arr[j] > temp) {
arr[j+1] = arr[j];
j--;
}
arr[j+1] = temp;
}
}
// Merge de dos subarreglos: arr[l..m] y arr[m+1..r]
void merge(int arr[], int l, int m, int r) {
int len1 = m - l + 1, len2 = r - m;
int *left = (int*)malloc(len1 * sizeof(int));
int *right = (int*)malloc(len2 * sizeof(int));
for (int i = 0; i < len1; i++)
left[i] = arr[l + i];
for (int i = 0; i < len2; i++)
right[i] = arr[m + 1 + i];
int i = 0, j = 0, k = l;
while (i < len1 && j < len2) {
if (left[i] <= right[j])
arr[k++] = left[i++];
else
arr[k++] = right[j++];
}
while (i < len1)
arr[k++] = left[i++];
while (j < len2)
arr[k++] = right[j++];
free(left);
free(right);
}
void timSort(int arr[], int n) {
for (int i = 0; i < n; i += MIN_RUN) {
int right = (i + MIN_RUN - 1 < n) ? i + MIN_RUN - 1 : n - 1;
insertionSort(arr, i, right);
}
for (int size = MIN_RUN; size < n; size = 2 * size) {
for (int left = 0; left < n; left += 2 * size) {
int mid = left + size - 1;
int right = (left + 2 * size - 1 < n) ? left + 2 * size - 1 : n - 1;
if (mid < right)
merge(arr, left, mid, right);
}
}
}
int main() {
int arr[] = {5, 21, 7, 23, 19, 10, 3, 15, 1, 9};
int n = sizeof(arr)/sizeof(arr[0]);
printf("Array original: ");
for (int i = 0; i < n; i++)
printf("%d ", arr[i]);
printf("
");
timSort(arr, n);
printf("Array ordenado: ");
for (int i = 0; i < n; i++)
printf("%d ", arr[i]);
printf("
");
return 0;
}
/* TimSort en C++ (versión simplificada) */
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
const int MIN_RUN = 32;
void insertionSort(vector<int>& arr, int left, int right) {
for (int i = left + 1; i <= right; i++) {
int temp = arr[i];
int j = i - 1;
while (j >= left && arr[j] > temp) {
arr[j+1] = arr[j];
j--;
}
arr[j+1] = temp;
}
}
void merge(vector<int>& arr, int l, int m, int r) {
int len1 = m - l + 1, len2 = r - m;
vector<int> left(arr.begin() + l, arr.begin() + m + 1);
vector<int> right(arr.begin() + m + 1, arr.begin() + r + 1);
int i = 0, j = 0, k = l;
while (i < len1 && j < len2) {
if (left[i] <= right[j])
arr[k++] = left[i++];
else
arr[k++] = right[j++];
}
while (i < len1)
arr[k++] = left[i++];
while (j < len2)
arr[k++] = right[j++];
}
void timSort(vector<int>& arr) {
int n = arr.size();
for (int i = 0; i < n; i += MIN_RUN) {
insertionSort(arr, i, min(i + MIN_RUN - 1, n - 1));
}
for (int size = MIN_RUN; size < n; size *= 2) {
for (int left = 0; left < n; left += 2 * size) {
int mid = left + size - 1;
int right = min(left + 2 * size - 1, n - 1);
if (mid < right)
merge(arr, left, mid, right);
}
}
}
int main() {
vector<int> arr = {5, 21, 7, 23, 19, 10, 3, 15, 1, 9};
cout << "Array original: ";
for (int num : arr)
cout << num << " ";
cout << endl;
timSort(arr);
cout << "Array ordenado: ";
for (int num : arr)
cout << num << " ";
cout << endl;
return 0;
}
/* TimSort en C# (versión simplificada) */
using System;
public class TimSortClass {
const int MIN_RUN = 32;
// Insertion Sort para ordenar un subarreglo de 'left' a 'right'
public static void InsertionSort(int[] arr, int left, int right) {
for (int i = left + 1; i <= right; i++) {
int temp = arr[i];
int j = i - 1;
while (j >= left && arr[j] > temp) {
arr[j+1] = arr[j];
j--;
}
arr[j+1] = temp;
}
}
// Fusiona dos subarreglos: arr[l..m] y arr[m+1..r]
public static void Merge(int[] arr, int l, int m, int r) {
int len1 = m - l + 1, len2 = r - m;
int[] left = new int[len1];
int[] right = new int[len2];
Array.Copy(arr, l, left, 0, len1);
Array.Copy(arr, m+1, right, 0, len2);
int i = 0, j = 0, k = l;
while (i < len1 && j < len2) {
if (left[i] <= right[j])
arr[k++] = left[i++];
else
arr[k++] = right[j++];
}
while (i < len1)
arr[k++] = left[i++];
while (j < len2)
arr[k++] = right[j++];
}
// Función principal de TimSort
public static void TimSort(int[] arr) {
int n = arr.Length;
for (int i = 0; i < n; i += MIN_RUN) {
InsertionSort(arr, i, Math.Min(i + MIN_RUN - 1, n - 1));
}
for (int size = MIN_RUN; size < n; size *= 2) {
for (int left = 0; left < n; left += 2 * size) {
int mid = left + size - 1;
int right = Math.Min(left + 2 * size - 1, n - 1);
if (mid < right)
Merge(arr, left, mid, right);
}
}
}
public static void Main() {
int[] arr = {5, 21, 7, 23, 19, 10, 3, 15, 1, 9};
Console.WriteLine("Array original: " + string.Join(" ", arr));
TimSort(arr);
Console.WriteLine("Array ordenado: " + string.Join(" ", arr));
}
}
Ordenamiento por Shell
El ordenamiento por Shell es una versión mejorada del Insertion Sort que permite intercambiar elementos distantes. Divide el arreglo en subarreglos usando un ''gap'' (intervalo) que se reduce progresivamente. Su rendimiento depende fuertemente de la secuencia de intervalos utilizada.
Complejidad
- Complejidad Temporal:
O(n log n) mejor caso, O(n^1.5) promedio y peor caso
- Complejidad Espacial:
O(1)
Implementación
/* ShellSort en Java */
// Implementa ShellSort utilizando una secuencia decreciente de gap.
public class ShellSort {
public static void shellSort(int arr[]) {
int n = arr.length;
// Inicializa gap y lo reduce progresivamente
for (int gap = n / 2; gap > 0; gap /= 2) {
// Realiza Insertion Sort para elementos con separacion 'gap'
for (int i = gap; i < n; i++) {
int temp = arr[i];
int j;
for (j = i; j >= gap && arr[j - gap] > temp; j -= gap) {
arr[j] = arr[j - gap];
}
arr[j] = temp;
}
}
}
public static void main(String[] args) {
int arr[] = {12, 34, 54, 2, 3};
System.out.println("Array original:");
for (int num : arr)
System.out.print(num + " ");
System.out.println();
shellSort(arr);
System.out.println("Array ordenado:");
for (int num : arr)
System.out.print(num + " ");
}
}
# ShellSort en Python
def shellSort(arr):
n = len(arr)
gap = n // 2
while gap > 0:
for i in range(gap, n):
temp = arr[i]
j = i
while j >= gap and arr[j - gap] > temp:
arr[j] = arr[j - gap]
j -= gap
arr[j] = temp
gap //= 2
if __name__ == "__main__":
arr = [12, 34, 54, 2, 3]
print("Array original:", arr)
shellSort(arr)
print("Array ordenado:", arr)
/* ShellSort en JavaScript */
// Ordena el arreglo utilizando una secuencia decreciente de gap.
function shellSort(arr) {
let n = arr.length;
for (let gap = Math.floor(n/2); gap > 0; gap = Math.floor(gap/2)) {
for (let i = gap; i < n; i++) {
let temp = arr[i];
let j = i;
while (j >= gap && arr[j - gap] > temp) {
arr[j] = arr[j - gap];
j -= gap;
}
arr[j] = temp;
}
}
return arr;
}
// Ejemplo de uso:
let arr = [12, 34, 54, 2, 3];
console.log("Array original:", arr);
console.log("Array ordenado:", shellSort(arr));
/* ShellSort en TypeScript */
function shellSort(arr: number[]): number[] {
let n: number = arr.length;
for (let gap = Math.floor(n / 2); gap > 0; gap = Math.floor(gap / 2)) {
for (let i = gap; i < n; i++) {
let temp: number = arr[i];
let j: number = i;
while (j >= gap && arr[j - gap] > temp) {
arr[j] = arr[j - gap];
j -= gap;
}
arr[j] = temp;
}
}
return arr;
}
// Ejemplo de uso:
const arr: number[] = [12, 34, 54, 2, 3];
console.log("Array original:", arr);
console.log("Array ordenado:", shellSort(arr));
/* ShellSort en Go */
package main
import "fmt"
func shellSort(arr []int) {
n := len(arr)
for gap := n / 2; gap > 0; gap /= 2 {
for i := gap; i < n; i++ {
temp := arr[i]
j := i
for j >= gap && arr[j-gap] > temp {
arr[j] = arr[j-gap]
j -= gap
}
arr[j] = temp
}
}
}
func main() {
arr := []int{12, 34, 54, 2, 3}
fmt.Println("Array original:", arr)
shellSort(arr)
fmt.Println("Array ordenado:", arr)
}
/* ShellSort en C */
#include <stdio.h>
void shellSort(int arr[], int n) {
for (int gap = n / 2; gap > 0; gap /= 2) {
for (int i = gap; i < n; i++) {
int temp = arr[i];
int j;
for (j = i; j >= gap && arr[j - gap] > temp; j -= gap) {
arr[j] = arr[j - gap];
}
arr[j] = temp;
}
}
}
int main() {
int arr[] = {12, 34, 54, 2, 3};
int n = sizeof(arr) / sizeof(arr[0]);
printf("Array original: ");
for (int i = 0; i < n; i++)
printf("%d ", arr[i]);
printf("
");
shellSort(arr, n);
printf("Array ordenado: ");
for (int i = 0; i < n; i++)
printf("%d ", arr[i]);
printf("
");
return 0;
}
/* ShellSort en C++ */
#include <iostream>
#include <vector>
using namespace std;
void shellSort(vector<int>& arr) {
int n = arr.size();
for (int gap = n / 2; gap > 0; gap /= 2) {
for (int i = gap; i < n; i++) {
int temp = arr[i];
int j = i;
while (j >= gap && arr[j - gap] > temp) {
arr[j] = arr[j - gap];
j -= gap;
}
arr[j] = temp;
}
}
}
int main() {
vector<int> arr = {12, 34, 54, 2, 3};
cout << "Array original: ";
for (int num : arr)
cout << num << " ";
cout << endl;
shellSort(arr);
cout << "Array ordenado: ";
for (int num : arr)
cout << num << " ";
cout << endl;
return 0;
}
/* ShellSort en C# */
using System;
public class ShellSortClass {
public static void ShellSort(int[] arr) {
int n = arr.Length;
for (int gap = n / 2; gap > 0; gap /= 2) {
for (int i = gap; i < n; i++) {
int temp = arr[i];
int j = i;
while (j >= gap && arr[j - gap] > temp) {
arr[j] = arr[j - gap];
j -= gap;
}
arr[j] = temp;
}
}
}
public static void Main() {
int[] arr = {12, 34, 54, 2, 3};
Console.WriteLine("Array original: " + string.Join(" ", arr));
ShellSort(arr);
Console.WriteLine("Array ordenado: " + string.Join(" ", arr));
}
}