En aquest tema, explorarem algunes estructures de dades avançades que són útils per a la resolució de problemes complexos i l'optimització del rendiment en Python. Aquestes estructures de dades inclouen piles, cues, deques, heaps i grafos. Aprendrem com utilitzar-les, les seves aplicacions i implementacions pràctiques.
Continguts
Piles (Stacks)
Què és una Pila?
Una pila és una estructura de dades que segueix el principi LIFO (Last In, First Out), és a dir, l'últim element que s'afegeix és el primer que es treu.
Operacions Bàsiques
- push(x): Afegeix l'element
xa la pila. - pop(): Treu i retorna l'element del cim de la pila.
- peek(): Retorna l'element del cim sense treure'l.
- is_empty(): Retorna
Truesi la pila està buida,Falseen cas contrari.
Implementació en Python
class Stack:
def __init__(self):
self.items = []
def push(self, item):
self.items.append(item)
def pop(self):
if not self.is_empty():
return self.items.pop()
else:
raise IndexError("pop from empty stack")
def peek(self):
if not self.is_empty():
return self.items[-1]
else:
raise IndexError("peek from empty stack")
def is_empty(self):
return len(self.items) == 0
def size(self):
return len(self.items)
# Exemple d'ús
stack = Stack()
stack.push(1)
stack.push(2)
print(stack.pop()) # Sortida: 2
print(stack.peek()) # Sortida: 1Cues (Queues)
Què és una Cua?
Una cua és una estructura de dades que segueix el principi FIFO (First In, First Out), és a dir, el primer element que s'afegeix és el primer que es treu.
Operacions Bàsiques
- enqueue(x): Afegeix l'element
xa la cua. - dequeue(): Treu i retorna l'element del front de la cua.
- front(): Retorna l'element del front sense treure'l.
- is_empty(): Retorna
Truesi la cua està buida,Falseen cas contrari.
Implementació en Python
class Queue:
def __init__(self):
self.items = []
def enqueue(self, item):
self.items.insert(0, item)
def dequeue(self):
if not self.is_empty():
return self.items.pop()
else:
raise IndexError("dequeue from empty queue")
def front(self):
if not self.is_empty():
return self.items[-1]
else:
raise IndexError("front from empty queue")
def is_empty(self):
return len(self.items) == 0
def size(self):
return len(self.items)
# Exemple d'ús
queue = Queue()
queue.enqueue(1)
queue.enqueue(2)
print(queue.dequeue()) # Sortida: 1
print(queue.front()) # Sortida: 2Deques (Double-ended Queues)
Què és una Deque?
Una deque (Double-ended Queue) és una estructura de dades que permet l'addició i eliminació d'elements tant pel front com pel final.
Operacions Bàsiques
- append(x): Afegeix l'element
xal final de la deque. - appendleft(x): Afegeix l'element
xal front de la deque. - pop(): Treu i retorna l'element del final de la deque.
- popleft(): Treu i retorna l'element del front de la deque.
- is_empty(): Retorna
Truesi la deque està buida,Falseen cas contrari.
Implementació en Python
from collections import deque # Creació d'una deque d = deque() # Afegeix elements d.append(1) d.appendleft(2) # Treu elements print(d.pop()) # Sortida: 1 print(d.popleft()) # Sortida: 2
Heaps
Què és un Heap?
Un heap és una estructura de dades especialitzada que satisfà la propietat de heap. En un min-heap, el valor del node pare és sempre menor o igual que els valors dels seus fills. En un max-heap, el valor del node pare és sempre major o igual que els valors dels seus fills.
Operacions Bàsiques
- heappush(heap, x): Afegeix l'element
xal heap. - heappop(heap): Treu i retorna l'element més petit del heap.
- heapify(x): Converteix la llista
xen un heap.
Implementació en Python
import heapq # Creació d'un min-heap heap = [] # Afegeix elements heapq.heappush(heap, 3) heapq.heappush(heap, 1) heapq.heappush(heap, 2) # Treu l'element més petit print(heapq.heappop(heap)) # Sortida: 1
Grafos (Graphs)
Què és un Grafo?
Un grafo és una estructura de dades que consisteix en un conjunt de nodes (o vèrtexs) i un conjunt d'arestes que connecten parells de nodes.
Representació d'un Grafo
Els grafos es poden representar de diverses maneres, incloent llistes d'adjacència i matrius d'adjacència.
Implementació en Python
Llista d'Adjacència
class Graph:
def __init__(self):
self.graph = {}
def add_edge(self, u, v):
if u not in self.graph:
self.graph[u] = []
self.graph[u].append(v)
def get_neighbors(self, u):
return self.graph.get(u, [])
# Exemple d'ús
g = Graph()
g.add_edge(1, 2)
g.add_edge(1, 3)
g.add_edge(2, 4)
print(g.get_neighbors(1)) # Sortida: [2, 3]Matriu d'Adjacència
import numpy as np
class GraphMatrix:
def __init__(self, num_nodes):
self.matrix = np.zeros((num_nodes, num_nodes))
def add_edge(self, u, v):
self.matrix[u][v] = 1
def get_neighbors(self, u):
return np.where(self.matrix[u] == 1)[0]
# Exemple d'ús
gm = GraphMatrix(5)
gm.add_edge(1, 2)
gm.add_edge(1, 3)
gm.add_edge(2, 4)
print(gm.get_neighbors(1)) # Sortida: [2 3]Exercicis Pràctics
Exercici 1: Implementació d'una Pila
Implementa una pila utilitzant una llista en Python i prova les operacions bàsiques.
Exercici 2: Implementació d'una Cua
Implementa una cua utilitzant una llista en Python i prova les operacions bàsiques.
Exercici 3: Utilització de Deques
Utilitza la classe deque de la biblioteca collections per implementar una cua de doble extrem i prova les operacions bàsiques.
Exercici 4: Treballant amb Heaps
Utilitza la biblioteca heapq per crear un min-heap i realitza operacions d'inserció i eliminació.
Exercici 5: Representació de Grafos
Implementa un grafo utilitzant una llista d'adjacència i una matriu d'adjacència. Afegeix algunes arestes i mostra els veïns d'un node donat.
Resum
En aquesta secció, hem explorat diverses estructures de dades avançades com piles, cues, deques, heaps i grafos. Hem après les seves operacions bàsiques i com implementar-les en Python. Aquestes estructures de dades són fonamentals per a la resolució de problemes complexos i l'optimització del rendiment en aplicacions reals.
Curs de Programació en Python
Mòdul 1: Introducció a Python
- Introducció a Python
- Configuració de l'Entorn de Desenvolupament
- Sintaxi de Python i Tipus de Dades Bàsics
- Variables i Constants
- Entrada i Sortida Bàsiques
Mòdul 2: Estructures de Control
Mòdul 3: Funcions i Mòduls
- Definició de Funcions
- Arguments de Funció
- Funcions Lambda
- Mòduls i Paquets
- Visió General de la Biblioteca Estàndard
Mòdul 4: Estructures de Dades
Mòdul 5: Programació Orientada a Objectes
Mòdul 6: Gestió de Fitxers
- Lectura i Escriptura de Fitxers
- Treballant amb Fitxers CSV
- Gestió de Dades JSON
- Operacions amb Fitxers i Directoris
Mòdul 7: Gestió d'Errors i Excepcions
Mòdul 8: Temes Avançats
- Decoradors
- Generadors
- Gestors de Context
- Concurrència: Fils i Processos
- Asyncio per a Programació Asíncrona
Mòdul 9: Proves i Depuració
- Introducció a les Proves
- Proves Unitàries amb unittest
- Desenvolupament Guiat per Proves
- Tècniques de Depuració
- Ús de pdb per a la Depuració
Mòdul 10: Desenvolupament Web amb Python
- Introducció al Desenvolupament Web
- Conceptes Bàsics del Framework Flask
- Construcció d'APIs REST amb Flask
- Introducció a Django
- Construcció d'Aplicacions Web amb Django
Mòdul 11: Ciència de Dades amb Python
- Introducció a la Ciència de Dades
- NumPy per al Càlcul Numèric
- Pandas per a la Manipulació de Dades
- Matplotlib per a la Visualització de Dades
- Introducció al Machine Learning amb scikit-learn
