Академический Документы
Профессиональный Документы
Культура Документы
Motivacin
Estamos implementando un editor de textos sencillo
Un documento est formado por un conjunto de lneas, cada
una de ellas formadas por un conjunto de caracteres
Usaremos una lista para las lneas y un vector dinmico
Hay problemas tanto al dar enter
para guardar el contenido de cada lnea
como para mover
linea activa
cursor
hendrerit an. Qui ut wisi vocibus suscipiantur,
Motivacin
Esta estructura permite aadir lineas en cualquier posicin y
modificar una linea aadiendo, borrando o modificando
caracteres
Sin embargo conforme se edita el texto, la estructura de
datos facilita el pasar de una lnea a la siguiente, pero no a la
anterior
La lista enlazada no es suficientemente flexible
ListaDEnlazada
cabecera
cola
0
dato1
dato2
dato3
template<class
template<class T>
T>
class
class Nodo
Nodo {{
public:
public:
TT dato;
dato;
Nodo
Nodo *ant,
*ant, *sig;
*sig;
};
};
Nodo(T
Nodo(T &aDato,
&aDato, Nodo
Nodo *aAnt,
*aAnt, Nodo
Nodo *aSig):
*aSig):
dato(aDato),
dato(aDato), ant(aAnt),
ant(aAnt), sig(aSig)
sig(aSig) {}
{}
Nodo es una clase oculta, por lo que da igual que est todo pblico porque nadie va a manipularla
ant
dato
sig
Insercin al principio
0
Nodo<T>
Nodo<T> *nuevo;
*nuevo;
nuevo
=
nuevo = new
new Nodo<T>(dato,
Nodo<T>(dato, 0,
0, cabecera);
cabecera);
nuevo
dato
cabecera
dato 1
//
// Caso
Caso especial:
especial: si
si la
la lista
lista estaba
estaba
//
// vaca,
vaca, poner
poner la
la cola
cola apuntando
apuntando al
al nodo
nodo
if
if (cola
(cola ==
== 0)
0)
cola
cola == nuevo;
nuevo;
if
if (cabecera
(cabecera !=
!= 0)
0)
cabecera->ant
cabecera->ant == nuevo
nuevo
cabecera
cabecera == nuevo;
nuevo;
0
0
nuevo
dato
cabecera
dato 1
Insercin al final
Nodo<T>
Nodo<T> *nuevo;
*nuevo;
nuevo
nuevo == new
new Nodo<T>(dato,
Nodo<T>(dato, cola,
cola, 0);
0);
nuevo
cola
...
//
// Caso
Caso especial:
especial: si
si la
la lista
lista estaba
estaba vaca,
vaca,
//
// poner
poner la
la cola
cola apuntando
apuntando al
al nodo
nodo
if
if (cabecera
(cabecera ==
== 0)
0)
cabecera
cabecera == nuevo;
nuevo;
if
if (cola
(cola !=
!= 0)
0)
cola->sig
cola->sig == nuevo
nuevo
cola
=
nuevo
cola = nuevo
nuevo
cola
...
dato
dato n
dato
dato n
0
7
Insercin en medio
Hacer mdulos difciles internamente, pero interfaz sencilla fuera.
dato
nuevo
Nodo<T>
Nodo<T>
nuevo
nuevo ==
*nuevo;
*nuevo;
new
new Nodo<T>(dato,
Nodo<T>(dato, p->ant,
p->ant, p);
p);
...
p->ant->sig
p->ant->sig == nuevo;
nuevo;
p->ant
=
nuevo;
p->ant = nuevo;
si el orden inverso:
p->ant = nuevo;
p->ant->ant->sig = nuevo;
// equivalente a
nuevo->ant->sig = nuevo
...
dato i
dato i+1
...
dato i+1
...
dato
nuevo
p
dato i
Nodo<T>
Nodo<T> *borrado
*borrado == cabecera;
cabecera;
dato 1
dato 2
...
dato 2
...
texto
cabecera
cabecera
cabecera == cabecera->sig
cabecera->sig
delete
borrado
delete borrado
borrado
if
if (cabecera
(cabecera !=
!= 0)
0)
cabecera->ant
cabecera->ant == 00
else
else
cola
cola == 00
dato 1
cabecera
10
Iteracin
template<class
template<class T>
T>
class
Iterador
{
class Iterador {
Nodo<T>
Nodo<T> *nodo;
*nodo;
friend
class
friend class ListaDEnlazada;
ListaDEnlazada;
public:
public:
Iterador(Nodo<T>
Iterador(Nodo<T> *aNodo)
*aNodo) :: nodo(aNodo)
nodo(aNodo) {}
{}
bool
bool
bool
bool
void
void
void
void
};
};
hayAnterior()
hayAnterior() {{ return
return nodo
nodo !=
!= 0;
0; }}
haySiguiente()
haySiguiente() {{ return
return nodo
nodo !=
!= 0;
0; }}
anterior()
anterior() {{ nodo
nodo == nodo->ant;
nodo->ant; }}
siguiente()
siguiente() {{ nodo
nodo == nodo->sig;
nodo->sig; }}
TT &dato()
&dato() {{ return
return nodo->dato;
nodo->dato; }}
11
La interfaz de la clase
ListaDEnlazada
template<class
template<class T>
T>
class
ListaDEnlazada
class ListaDEnlazada {{
Nodo<T>
Nodo<T> *cabecera,
*cabecera, *cola;
*cola;
public:
public:
ListaDEnlazada()
ListaDEnlazada() :: cabecera(0),
cabecera(0), cola(0)
cola(0) {}
{}
~ListaDEnlazada();
~ListaDEnlazada();
ListaDEnlazada(const
ListaDEnlazada(const ListaDEnlazada
ListaDEnlazada &l);
&l);
ListaDEnlazada
&operator=(ListaDEnlazada
ListaDEnlazada &operator=(ListaDEnlazada &l);
&l);
};
};
Iterador<T>
Iterador<T> iteradorInicio()
iteradorInicio() {{ return
return Iterador<T>(cabecera);
Iterador<T>(cabecera); }}
Iterador<T>
Iterador<T> iteradorFinal()
iteradorFinal() {{ return
return Iterador<T>(cola);
Iterador<T>(cola); }}
void
void insertarInicio(T
insertarInicio(T &dato);
&dato);
void
insertarFinal(T
&dato);
void insertarFinal(T &dato);
void
void insertar(Iterador<T>
insertar(Iterador<T> &i,
&i, TT &dato);
&dato);
void
borrarInicio();
void borrarInicio();
void
void borrarFinal();
borrarFinal();
void
borrar(Iterador<T>
void borrar(Iterador<T> &i);
&i);
TT &inicio()
{
return
cabecera->dato;
&inicio() { return cabecera->dato; }}
TT &final()
&final() {{ return
return cola->dato;
cola->dato; }}
12
Listas circulares
cola
dato 1
dato 2
dato 3
13
Matrices dispersas
14
en
una
matriz
fila
0000030000
0100000000
0000000000
0000000000
0000030000
0020000900
0000000000
(5, 3)
(1, 1)
(5, 3)
(2, 2)
valor
(7, 9)
15
Interfaz de la clase
MatrizDispersa
class
class ColMatrizDispersa
ColMatrizDispersa {{
public:
public:
int
int col;
col;
float
float val;
val;
};
};
ColMatrizDispersa(inta
ColMatrizDispersa(inta aCol,
aCol, float
float aVal)
aVal) ::
col(aCol),
col(aCol), val(aVal)
val(aVal) {}
{}
class
class FilaMatrizDispersa
FilaMatrizDispersa {{
ListaEnlazada<ColMatrizDispersa>
ListaEnlazada<ColMatrizDispersa> columnas;
columnas;
Iterador<ColMatrizDispersa>
Iterador<ColMatrizDispersa> buscar(int
buscar(int columna);
columna);
public:
public:
int
int fila;
fila;
FilaMatrizDispersa(int
FilaMatrizDispersa(int aFila):
aFila): fila(aFila),
fila(aFila), columnas()
columnas() {}
{}
};
};
float
float valor(int
valor(int columna);
columna);
void
cambiarValor(int
void cambiarValor(int columna,
columna, float
float valor);
valor);
Leccin 7: Listas doblemente enlazadas. Listas circulares y matrices dispersas
16
Interfaz de la clase
MatrizDispersa
class
class MatrizDispersa
MatrizDispersa {{
int
int maxFilas,
maxFilas, maxColumnas;
maxColumnas;
ListaEnlazada<FilaMatrizDispersa>
ListaEnlazada<FilaMatrizDispersa> filas;
filas;
Iterador<FilaMatrizDispersa>
Iterador<FilaMatrizDispersa> buscar(int
buscar(int fila);
fila);
public:
public:
MatrizDispersa(int
MatrizDispersa(int filas,
filas, int
int columnas):
columnas):
maxFilas(filas),
maxColumnas(columnas)
maxFilas(filas), maxColumnas(columnas) {}
{}
float
float valor(int
valor(int fila,
fila,
void
cambiarValor(int
void cambiarValor(int
};
};
int
int
int
int
int
int columna);
columna);
fila,
fila, int
int columna,
columna, float
float valor);
valor);
getNumFilas()
getNumFilas() {{ return
return maxFilas;
maxFilas; }}
getNumColumnas()
getNumColumnas() {{ return
return maxColumnas;
maxColumnas; }}
17
Implementacin de la Matriz
Dispersa
Iterador
Iterador FilaMatrizDispersa::buscar(int
FilaMatrizDispersa::buscar(int columna)
columna) {{
Iterador<ColMatrizDispersa>
Iterador<ColMatrizDispersa> ii == columnas.iterador();
columnas.iterador();
while
(i.haySiguiente()
&&
i.dato().col
while (i.haySiguiente() && i.dato().col << columna)
columna) {{
i.siguiente();
i.siguiente();
}}
return
return i;
i;
}}
float
float FilaMatrizDispersa::valor(int
FilaMatrizDispersa::valor(int columna)
columna) {{
Iterador<ColMatrizDispersa>
Iterador<ColMatrizDispersa> ii == buscar(columna);
buscar(columna);
if
if (i.haySiguiente()
(i.haySiguiente() &&
&& i.dato().col
i.dato().col ==
== columna)
columna) {{
return
return i.dato().val;
i.dato().val;
}}
}}
return
return 0;
0;
void
void FilaMatrizDispersa::cambiarValor(int
FilaMatrizDispersa::cambiarValor(int columna,
columna, float
float valor)
valor) {{
Iterador<ColMatrizDispersa>
Iterador<ColMatrizDispersa> ii == buscar(columna);
buscar(columna);
}}
if
if (i.haySiguiente()
(i.haySiguiente() &&
&& i.dato().col
i.dato().col ==
== columna)
columna) {{
i.dato().val
i.dato().val == valor;
valor;
}}
else
else {{
columnas.insertar(i,
ColMatrizDispersa(columna,
valor));
Leccin 7: Listas
doblemente enlazadas. Listas circulares y matrices
dispersas
columnas.insertar(i,
ColMatrizDispersa(columna,
valor));
}}
18
Implementacin de la Matriz
Dispersa
Iterador<FilaMatrizDispersa>
Iterador<FilaMatrizDispersa> MatrizDispersa::buscar(int
MatrizDispersa::buscar(int fila)
fila) {{
Iterador<FilaMatrizDispersa>
Iterador<FilaMatrizDispersa> ii == filas.iterador();
filas.iterador();
while
while (i.haySiguiente()
(i.haySiguiente() &&
&& i.dato().fila
i.dato().fila << fila)
fila) {{
i.siguiente();
i.siguiente();
}}
}}
return
return i;
i;
float
float MatrizDispersa::valor(int
MatrizDispersa::valor(int fila,
fila, int
int columna)
columna) {{
Iterador<FilaMatrizDispersa>
Iterador<FilaMatrizDispersa> ii == buscar(fila);
buscar(fila);
if
if (i.haySiguiente()
(i.haySiguiente() &&
&& i.dato().fila
i.dato().fila ==
== fila)
fila) {{
return
return i.dato().valor(columna);
i.dato().valor(columna);
}}
}}
return
return 0;
0;
void
void MatrizDispersa::cambiarValor(int
MatrizDispersa::cambiarValor(int fila,
fila, int
int columna,
columna, float
float
valor)
{
valor) {
Iterador<FilaMatrizDispersa>
Iterador<FilaMatrizDispersa> ii == buscar(fila);
buscar(fila);
if
if (!i.haySiguiente()
(!i.haySiguiente() ||
|| i.dato().fila
i.dato().fila !=
!= fila)
fila) {{
filas.insertar(i,
filas.insertar(i, FilaMatrizDispersa(fila));
FilaMatrizDispersa(fila));
}}
Leccin 7: Listas doblemente enlazadas. Listas circulares y matrices dispersas
}}
i.dato().cambiarValor(columna,
i.dato().cambiarValor(columna, valor);
valor);
19
Conclusiones
(listas doblemente enlazadas)
20
Conclusiones
(listas circulares y mat. dispersas)
21