Punteros y Estructuras enlazadas

Anuncio
ALGORITMOS Y
ESTRUCTURA DE DATOS
Punteros Estructuras Enlazadas Pilas
Punteros y direcciones de memoria
Un puntero es un tipo de dato, como todo tipo de dato se define por dos conjuntos:

Conjunto de valores
o

Direcciones de memoria
Conjunto de operaciones
o
Asignación


Estática

Mediante el operador de dirección int *p = & a;

Con el valor Nulo int *p = NULL
Dinámica: para crear o liberar instancias

Crear instancia int *p = new int();

Liberar instancia delete p;
int a = 25;
int* p1 = &a;
int* p2 = NULL;
float* q1 = NULL;
Asignaciones
*p1 = 30; //
*p2 = 10; //
p2 = p1; //
q1 = p1 ; //
diferentes
modifica el valor de a
ERROR no se instancio a p2
ps apunta a la misma dirección que p1
ERROR los punteros son con tipo y por definición apuntan a tipos
C/C++ y los operadores de dirección e indireccion
C provee los operadores

& que es un operador de dirección: antepuesto a un identificador indica la dirección de memoria del
mismo.

* operador de induración o desreferenciacion: antepuesto a un puntero indica el contenido de la
dirección de memoria a la que apunta el puntero.

-> operador de acceso a un miembro de una struct apuntada por un puntero equivale a
(*struct).miembro.
2
Struct TR {
int a;
int b;
};
int x = 25;
int* p = &x;
TR r;
TR* pr
Asignación dinámica
new crea una instancia del puntero, toma como valor la dirección de memoria creada, se dice que apunta a
esa dirección de memoria.
delete libera la instancia creada por new.
int* p = new int();
Crea una instancia de p, a la dirección creada se accede con el operador de indireccion, *p y es un dato de tipo
entero
TR* pro = new TR();
Crea una instancia de TR, a la dirección creada se accede con el operador de indireccion, *pro y es un dato de
tipo struct TR. (*pro).a es el entero correspondiente al campo a de la struct TR apuntada por el puntero pro
delete p;
delete pro; eliminan las instancias creadas
Estructuras secuenciales Vs. Estructuras enlazadas
Estructuras secuenciales:

El primer elemento lógico coincide con el primer elemento físico

El siguiente elemento lógico coincide con el siguiente elemento físico
Estructuras enlazadas:

Se debe conocer la posición del primer elemento lógico ya que no necesariamente coincide con el
primer elemento físico

Cada posición tiene una struct (nodo) con la información y la referencia al siguiente elemento lógico
que no necesariamente es el siguiente fisico
A
B
3
B
D
-1
C
A
0
D
C
1
Tipos de estructuras

Lineales
o
Pilas
o
Colas
o
Listas (SE, Circ, DE, CircDE

Arboles

Grafos
3
Las estructuras enlazadas pueden implementarse con vectores, en este caso no se resolvería la restricción de
tamaño fijo de esta estructura de dato. El vector requiere el conocimiento a priori del tamaño físico máximo.
Para resolver esta debilidad se pueden implementar con punteros de podo de generar los nodos que se
requieran en tiempo de ejecución, en este caso se tendrán exactamente la cantidad de posiciones que cada
aplicación requiera. Esta ventaja es a a un costo: Como el siguiente lógico puede estar en una posición de
memoria no contigua, el nodo debe tener una referencia precisa al siguiente elemento por lo que requiere un
puntero que referencie al siguiente elemento lógica. Esta estructura que tiene un puntero a una estructura del
mismo tipo de la cual parte se la denomina estructura autoreferenciada
Nodo
struct Nodo {
int info;
Nodo* sgte;
};
Estructuras enlazadas implementadas con Punteros
Para trabajar con estas estructuras es necesario:
1. Declarar la estructura del nodo
2. Definir una variable de control de la estructura  de tipo puntero
3. Definir una variable para las distintas instancias  de tipo puntero
4. De finir una variable para contener la información  del tipo de la información
5. Crear la estructura  hacer apuntar a NULL a la variable de control de la estructura
6. Cargar la estructura
a. Tomar la información
b. Pedir memoria
c. Guardar la información
d. Actualizar los punteros
Pilas
Una pila es una estructura en la que los elementos se insertan delante del primero, se apilan; y cuando se saca, se
elimina el que está en el tope, son estructuras LIFO: Last In First Out.
Para la carga se pueden diferenciar dos situaciones, cuanto la pila esta vaci, es decir el puntero de contol (pila)
tiene el valor NULL o cuando la pila tiene datos
Acciones
Pedir memoria
Guardar la información
Enlazar el nodo
Actualizar la pila
Con pila Vacía
Nodo* Aux = new Nodo();
Aux->info = valor;
Aux->sgte = NULL;
Pila = Aux;
Función: push
void push(Nodo*& p, int v){
Nodo* Aux = new Nodo();
Aux->info = valor;
Aux->sgte = p;
p = Aux;
return;
}
Con pila con datos
Nodo* Aux = new Nodo();
Aux->info = valor;
Aux->sgte = Pila;
Pila = Aux
4
Con plantillas
template <typename T> struct Nodo {
T info;
Nodo<T>* sgte;
};
template <typename T> void push(Nodo<T>* &p, T v){
Nodo<T>* Aux = new Nodo<T>();
Aux->info = valor;
Aux->sgte = p;
p = Aux;
return;
}
Función: pop
int pop(Nodo* &p){
int x;
Nodo* Aux = p;
x = Aux->info;
Aux = Aux->sgte;
delete p;
return x;
}
Con plantillas
template <typename T> pop(Nodo<T>* &p){
T x;
Nodo<T>* Aux = p;
x = Aux->info;
Aux = Aux->sgte;
delete p;
return x;
}
Ejemplo de uso
int main(){
Nodo<int>* p = NULL;
push<int>(p,1);
push<int>(p,2);
push<int>(p,3);
while( p!=NULL ){
cout << pop<int>(p) << endl;
}
return 0;
}
Descargar