En aquest tema, explorarem diversos algoritmes d'ordenació avançats que són fonamentals per a la manipulació eficient de dades. Aquests algoritmes són més sofisticats que els mètodes bàsics com la bombolla o la selecció, i són essencials per a aplicacions que requereixen un rendiment òptim.
Índex
Introducció
Els algoritmes d'ordenació avançats són dissenyats per ser més eficients en termes de temps i espai comparats amb els mètodes bàsics. Aquests algoritmes són crucials per a la gestió de grans volums de dades i per a aplicacions que requereixen una resposta ràpida.
Objectius d'Aprenentatge
- Comprendre els principis fonamentals dels algoritmes d'ordenació avançats.
- Implementar aquests algoritmes en codi.
- Analitzar la complexitat temporal i espacial de cada algoritme.
- Aplicar els algoritmes a problemes pràctics.
Ordenació per Fusió (Merge Sort)
Descripció
L'ordenació per fusió és un algoritme de tipus "divideix i venceràs" que divideix la llista en subllistes més petites fins que cada subllista conté un sol element, i després les fusiona en una llista ordenada.
Pseudocodi
MergeSort(arr):
if length(arr) > 1:
mid = length(arr) // 2
left_half = arr[:mid]
right_half = arr[mid:]
MergeSort(left_half)
MergeSort(right_half)
i = j = k = 0
while i < len(left_half) and j < len(right_half):
if left_half[i] < right_half[j]:
arr[k] = left_half[i]
i += 1
else:
arr[k] = right_half[j]
j += 1
k += 1
while i < len(left_half):
arr[k] = left_half[i]
i += 1
k += 1
while j < len(right_half):
arr[k] = right_half[j]
j += 1
k += 1Implementació en Python
def merge_sort(arr):
if len(arr) > 1:
mid = len(arr) // 2
left_half = arr[:mid]
right_half = arr[mid:]
merge_sort(left_half)
merge_sort(right_half)
i = j = k = 0
while i < len(left_half) and j < len(right_half):
if left_half[i] < right_half[j]:
arr[k] = left_half[i]
i += 1
else:
arr[k] = right_half[j]
j += 1
k += 1
while i < len(left_half):
arr[k] = left_half[i]
i += 1
k += 1
while j < len(right_half):
arr[k] = right_half[j]
j += 1
k += 1Complexitat
- Pitjor cas: O(n log n)
- Millor cas: O(n log n)
- Cas mitjà: O(n log n)
- Espai: O(n)
Ordenació Ràpida (Quick Sort)
Descripció
L'ordenació ràpida és un altre algoritme de tipus "divideix i venceràs" que selecciona un element com a pivot i particiona la llista en dues subllistes: una amb elements menors que el pivot i una altra amb elements majors.
Pseudocodi
QuickSort(arr, low, high):
if low < high:
pi = Partition(arr, low, high)
QuickSort(arr, low, pi - 1)
QuickSort(arr, pi + 1, high)
Partition(arr, low, high):
pivot = arr[high]
i = low - 1
for j in range(low, high):
if arr[j] < pivot:
i += 1
arr[i], arr[j] = arr[j], arr[i]
arr[i + 1], arr[high] = arr[high], arr[i + 1]
return i + 1Implementació en Python
def quick_sort(arr, low, high):
if low < high:
pi = partition(arr, low, high)
quick_sort(arr, low, pi - 1)
quick_sort(arr, pi + 1, high)
def partition(arr, low, high):
pivot = arr[high]
i = low - 1
for j in range(low, high):
if arr[j] < pivot:
i += 1
arr[i], arr[j] = arr[j], arr[i]
arr[i + 1], arr[high] = arr[high], arr[i + 1]
return i + 1Complexitat
- Pitjor cas: O(n^2)
- Millor cas: O(n log n)
- Cas mitjà: O(n log n)
- Espai: O(log n)
Ordenació per Radix (Radix Sort)
Descripció
L'ordenació per radix és un algoritme no comparatiu que ordena els nombres processant cada dígit individualment. És especialment útil per a ordenar nombres enters.
Pseudocodi
RadixSort(arr):
max_val = max(arr)
exp = 1
while max_val // exp > 0:
CountingSort(arr, exp)
exp *= 10
CountingSort(arr, exp):
n = len(arr)
output = [0] * n
count = [0] * 10
for i in range(n):
index = (arr[i] // exp) % 10
count[index] += 1
for i in range(1, 10):
count[i] += count[i - 1]
i = n - 1
while i >= 0:
index = (arr[i] // exp) % 10
output[count[index] - 1] = arr[i]
count[index] -= 1
i -= 1
for i in range(n):
arr[i] = output[i]Implementació en Python
def counting_sort(arr, exp):
n = len(arr)
output = [0] * n
count = [0] * 10
for i in range(n):
index = (arr[i] // exp) % 10
count[index] += 1
for i in range(1, 10):
count[i] += count[i - 1]
i = n - 1
while i >= 0:
index = (arr[i] // exp) % 10
output[count[index] - 1] = arr[i]
count[index] -= 1
i -= 1
for i in range(n):
arr[i] = output[i]
def radix_sort(arr):
max_val = max(arr)
exp = 1
while max_val // exp > 0:
counting_sort(arr, exp)
exp *= 10Complexitat
- Pitjor cas: O(nk)
- Millor cas: O(nk)
- Cas mitjà: O(nk)
- Espai: O(n + k)
Ordenació per Cistelles (Bucket Sort)
Descripció
L'ordenació per cistelles distribueix els elements en diverses cistelles, les ordena individualment i després les combina. És especialment útil per a dades que es distribueixen uniformement.
Pseudocodi
BucketSort(arr):
n = len(arr)
max_val = max(arr)
size = max_val / n
buckets = [[] for _ in range(n)]
for i in range(n):
j = int(arr[i] / size)
if j != n:
buckets[j].append(arr[i])
else:
buckets[n - 1].append(arr[i])
for i in range(n):
InsertionSort(buckets[i])
result = []
for i in range(n):
result.extend(buckets[i])
return result
InsertionSort(bucket):
for i in range(1, len(bucket)):
up = bucket[i]
j = i - 1
while j >= 0 and bucket[j] > up:
bucket[j + 1] = bucket[j]
j -= 1
bucket[j + 1] = upImplementació en Python
def insertion_sort(bucket):
for i in range(1, len(bucket)):
up = bucket[i]
j = i - 1
while j >= 0 and bucket[j] > up:
bucket[j + 1] = bucket[j]
j -= 1
bucket[j + 1] = up
def bucket_sort(arr):
n = len(arr)
max_val = max(arr)
size = max_val / n
buckets = [[] for _ in range(n)]
for i in range(n):
j = int(arr[i] / size)
if j != n:
buckets[j].append(arr[i])
else:
buckets[n - 1].append(arr[i])
for i in range(n):
insertion_sort(buckets[i])
result = []
for i in range(n):
result.extend(buckets[i])
return resultComplexitat
- Pitjor cas: O(n^2)
- Millor cas: O(n + k)
- Cas mitjà: O(n + k)
- Espai: O(n)
Exercicis Pràctics
Exercici 1: Implementació de Merge Sort
Implementa l'algoritme Merge Sort en el teu llenguatge de programació preferit i prova'l amb una llista de nombres enters.
Exercici 2: Anàlisi de Quick Sort
Implementa l'algoritme Quick Sort i analitza el seu rendiment amb diferents conjunts de dades, incloent llistes ja ordenades, llistes inversament ordenades i llistes amb elements aleatoris.
Exercici 3: Radix Sort amb Nombres Negatius
Modifica l'algoritme Radix Sort per a que pugui ordenar llistes que continguin nombres negatius.
Exercici 4: Bucket Sort per a Nombres Reals
Implementa l'algoritme Bucket Sort per a ordenar una llista de nombres reals entre 0 i 1.
Conclusió
En aquesta secció, hem explorat diversos algoritmes d'ordenació avançats, incloent Merge Sort, Quick Sort, Radix Sort i Bucket Sort. Aquests algoritmes són fonamentals per a la manipulació eficient de dades i tenen aplicacions en una àmplia varietat de camps. Hem vist com implementar-los, analitzar la seva complexitat i aplicar-los a problemes pràctics. Amb aquesta base, estàs preparat per abordar problemes d'ordenació més complexos i optimitzar el rendiment de les teves aplicacions.
Algoritmes Avançats
Mòdul 1: Introducció als Algoritmes Avançats
Mòdul 2: Algoritmes d'Optimització
- Programació Lineal
- Algoritmes d'Optimització Combinatòria
- Algoritmes Genètics
- Optimització de Colònia de Formigues
Mòdul 3: Algoritmes en Grafs
- Representació de Grafs
- Cerca en Grafs: BFS i DFS
- Algoritmes de Camins Mínims
- Algoritmes de Flux Màxim
- Algoritmes d'Aparellament en Grafs
Mòdul 4: Algoritmes de Cerca i Ordenació
Mòdul 5: Algoritmes d'Aprenentatge Automàtic
- Introducció a l'Aprenentatge Automàtic
- Algoritmes de Classificació
- Algoritmes de Regressió
- Xarxes Neuronals i Deep Learning
- Algoritmes de Clustering
Mòdul 6: Casos d'Estudi i Aplicacions
- Optimització en la Indústria
- Aplicacions de Grafs en Xarxes Socials
- Cerca i Ordenació en Grans Volums de Dades
- Aplicacions d'Aprenentatge Automàtic en la Vida Real
