En aquest tema, aprendrem com implementar una pila, una estructura de dades fonamental en la programació. Les piles segueixen el principi LIFO (Last In, First Out), és a dir, l'últim element que entra és el primer que surt. Veurem com implementar una pila utilitzant arrays i llistes enllaçades, i també discutirem les operacions bàsiques que es poden realitzar sobre una pila.
Conceptes Clau
Abans de començar amb la implementació, repassem les operacions bàsiques d'una pila:
- Push: Afegeix un element al cim de la pila.
- Pop: Elimina i retorna l'element del cim de la pila.
- Peek: Retorna l'element del cim de la pila sense eliminar-lo.
- isEmpty: Comprova si la pila està buida.
- Size: Retorna el nombre d'elements a la pila.
Implementació Utilitzant Arrays
Avantatges i Desavantatges
Avantatges:
- Accés ràpid als elements mitjançant l'índex.
- Implementació senzilla.
Desavantatges:
- Capacitat fixa (cal definir la mida màxima de la pila).
- Pot requerir més espai de memòria si la mida màxima és gran.
Codi d'Exemple
class PilaArray:
def __init__(self, capacitat):
self.capacitat = capacitat
self.pila = [None] * capacitat
self.cim = -1
def push(self, element):
if self.cim == self.capacitat - 1:
raise Exception("La pila està plena")
self.cim += 1
self.pila[self.cim] = element
def pop(self):
if self.is_empty():
raise Exception("La pila està buida")
element = self.pila[self.cim]
self.pila[self.cim] = None
self.cim -= 1
return element
def peek(self):
if self.is_empty():
raise Exception("La pila està buida")
return self.pila[self.cim]
def is_empty(self):
return self.cim == -1
def size(self):
return self.cim + 1
# Exemple d'ús
pila = PilaArray(5)
pila.push(10)
pila.push(20)
print(pila.pop()) # Sortida: 20
print(pila.peek()) # Sortida: 10
print(pila.size()) # Sortida: 1Implementació Utilitzant Llistes Enllaçades
Avantatges i Desavantatges
Avantatges:
- Capacitat dinàmica (no cal definir la mida màxima).
- Ús eficient de la memòria.
Desavantatges:
- Accés més lent als elements (cal recórrer la llista).
Codi d'Exemple
class Node:
def __init__(self, valor):
self.valor = valor
self.seguent = None
class PilaLlistaEnllaçada:
def __init__(self):
self.cim = None
self._size = 0
def push(self, element):
nou_node = Node(element)
nou_node.seguent = self.cim
self.cim = nou_node
self._size += 1
def pop(self):
if self.is_empty():
raise Exception("La pila està buida")
element = self.cim.valor
self.cim = self.cim.seguent
self._size -= 1
return element
def peek(self):
if self.is_empty():
raise Exception("La pila està buida")
return self.cim.valor
def is_empty(self):
return self.cim is None
def size(self):
return self._size
# Exemple d'ús
pila = PilaLlistaEnllaçada()
pila.push(10)
pila.push(20)
print(pila.pop()) # Sortida: 20
print(pila.peek()) # Sortida: 10
print(pila.size()) # Sortida: 1Exercicis Pràctics
Exercici 1: Implementació de la Pila amb Arrays
Implementa una pila utilitzant arrays amb les operacions bàsiques (push, pop, peek, is_empty, size). Prova la teva implementació amb diferents casos de prova.
Exercici 2: Implementació de la Pila amb Llistes Enllaçades
Implementa una pila utilitzant llistes enllaçades amb les operacions bàsiques (push, pop, peek, is_empty, size). Prova la teva implementació amb diferents casos de prova.
Solucions
Solució a l'Exercici 1
class PilaArray:
def __init__(self, capacitat):
self.capacitat = capacitat
self.pila = [None] * capacitat
self.cim = -1
def push(self, element):
if self.cim == self.capacitat - 1:
raise Exception("La pila està plena")
self.cim += 1
self.pila[self.cim] = element
def pop(self):
if self.is_empty():
raise Exception("La pila està buida")
element = self.pila[self.cim]
self.pila[self.cim] = None
self.cim -= 1
return element
def peek(self):
if self.is_empty():
raise Exception("La pila està buida")
return self.pila[self.cim]
def is_empty(self):
return self.cim == -1
def size(self):
return self.cim + 1
# Prova
pila = PilaArray(5)
pila.push(10)
pila.push(20)
print(pila.pop()) # Sortida: 20
print(pila.peek()) # Sortida: 10
print(pila.size()) # Sortida: 1Solució a l'Exercici 2
class Node:
def __init__(self, valor):
self.valor = valor
self.seguent = None
class PilaLlistaEnllaçada:
def __init__(self):
self.cim = None
self._size = 0
def push(self, element):
nou_node = Node(element)
nou_node.seguent = self.cim
self.cim = nou_node
self._size += 1
def pop(self):
if self.is_empty():
raise Exception("La pila està buida")
element = self.cim.valor
self.cim = self.cim.seguent
self._size -= 1
return element
def peek(self):
if self.is_empty():
raise Exception("La pila està buida")
return self.cim.valor
def is_empty(self):
return self.cim is None
def size(self):
return self._size
# Prova
pila = PilaLlistaEnllaçada()
pila.push(10)
pila.push(20)
print(pila.pop()) # Sortida: 20
print(pila.peek()) # Sortida: 10
print(pila.size()) # Sortida: 1Resum
En aquesta secció, hem après com implementar una pila utilitzant arrays i llistes enllaçades. Hem vist les operacions bàsiques que es poden realitzar sobre una pila i hem proporcionat exemples de codi per a cada implementació. També hem inclòs exercicis pràctics per reforçar els conceptes apresos. En el següent tema, explorarem les aplicacions de les piles en la programació.
Curs d'Estructures de Dades
Mòdul 1: Introducció a les Estructures de Dades
- Què són les Estructures de Dades?
- Importància de les Estructures de Dades en la Programació
- Tipus d'Estructures de Dades
Mòdul 2: Llistes
- Introducció a les Llistes
- Llistes Enllaçades
- Llistes Doblement Enllaçades
- Llistes Circulars
- Exercicis amb Llistes
Mòdul 3: Piles
- Introducció a les Piles
- Operacions Bàsiques amb Piles
- Implementació de Piles
- Aplicacions de les Piles
- Exercicis amb Piles
Mòdul 4: Cues
- Introducció a les Cues
- Operacions Bàsiques amb Cues
- Cues Circulars
- Cues de Prioritat
- Exercicis amb Cues
Mòdul 5: Arbres
- Introducció als Arbres
- Arbres Binàries
- Arbres Binàries de Cerca
- Arbres AVL
- Arbres B
- Exercicis amb Arbres
Mòdul 6: Grafs
- Introducció als Grafs
- Representació de Grafs
- Algoritmes de Cerca en Grafs
- Algoritmes de Camins Mínims
- Aplicacions dels Grafs
- Exercicis amb Grafs
