You are on page 1of 9

Captulo 13. Listas enlazadas, pilas, colas y rboles.

1. Introduccin.
2. Listas enlazadas.
3. Pilas.
4. Colas.
5. rboles.
5.1. rboles binarios.
1
1. Introduccin.
!l"unas soluciones in#or$ticas e%i"en la utilizacin de ciertas
estructuras de datos, &ue per$iten la opti$izacin del #unciona$iento de los
pro"ra$as. 'a$os a tratar en este captulo al"unas de estas estructuras.
2. Listas enlazadas.
(na lista enlazada consiste en una sucesin de estructuras del $is$o
tipo, en las &ue uno de sus ca$pos ser un puntero a estructura del $is$o
tipo, de este $odo cada estructura podr apuntar a la si"uiente de la lista.
!de$s del ca$po de tipo puntero a estructura, e%istirn otros ca$pos para
"uardar la in#or$acin &ue sea necesaria. Las estructuras &ue #or$an la lista
se irn creando de #or$a din$ica )malloc* a $edida &ue se +an necesitando,
para conse"uir el $%i$o a,orro de $e$oria.
lista
Para crear este tipo de lista, debe declararse una +ariable de tipo
puntero a estructura de la lista )puntero lista en la #i"ura anterior*, &ue debe
$antenerse apuntando sie$pre al pri$er ele$ento de la lista, es decir a la
pri$era estructura, para no perderse el punto de entrada a la lista. Para indicar
&ue la lista est +aca puede "uardarse el +alor -(LL en dic,o puntero.
./. !0adir el pri$er ele$ento de una lista enlazada.
struct tlista{
long DNI;
char Nombre[25];
int Edad;
struct tlista *psig; //Puntero a siguiente
!;
"oid main#"oid$
{
struct tlista *lista % N&''; //Inicialmente "ac(a
struct tlista *p; //Puntero au)iliar

//*e crea el nue"o elemento + se carga con datos,
p%#struct tlista *$malloc#-*si.eo/#struct tlista$$;
scan/#012ld34 5p67DNI$; //lush#stdin$;
scan/#0128[9:n]34 p67Nombre$; //lush#stdin$;
scan/#01;d34 5p67Edad$; //lush#stdin$;
p67psig % N&'';
//Puntero a sigte de momento "ale N&''

i/ #lista %% N&''$ //*i lista est< "ac(a
{
lista % p; //Es el primer elemento de la lista
!
else
2
{

!
!
1eneral$ente las operaciones sobre la lista enlazada re&uieren
co$probar si est +aca, co$o se ,ace en el e/e$plo anterior.
(na lista enlazada tiene un solo punto de entrada, &ue es el puntero
&ue apunta al pri$er ele$ento de la lista. Para acceder a un ele$ento
cual&uiera, debe recorrerse la lista de #or$a secuencial ,asta encontrar el
ele$ento buscado. Para reconocer el 2lti$o ele$ento suele "rabarse el +alor
-(LL en el ca$po puntero a si"uiente. .sta ser la #or$a de detectar donde
#inaliza la lista. Por tanto, puede deducirse &ue el recorrido de una lista
enlazada se realiza en un solo sentido.
.%iste una serie de operaciones &ue son las bsicas a realizar sobre
una lista enlazada. -o ol+idar &ue la $ayora re&uieren +eri#icar si la lista est
+aca. 'ea$os al"unas de estas operaciones3
4 Insertar un nue+o ele$ento. .sta operacin tiene dos +ariantes3
a* Insercin al co$ienzo de la lista, el ele$ento nue+o ser el pri$er ele$ento.
.l puntero a si"uiente del nue+o ele$ento apuntar al &ue era el pri$er
ele$ento )1*. .sta operacin $odi#ica el puntero de acceso a la lista, &ue
de/ar de apuntar al &ue era el pri$er ele$ento, para pasar a apuntar al
ele$ento nue+o )2*.
p .le$ento nue+o

55
lista
./. (sando el tipo de estructura del e/e$plo anterior y suponiendo &ue el
puntero al co$ienzo se lla$a lista3
//*e crea el nue"o elemento + se carga con datos,
p%#struct tlista *$malloc#-*si.eo/#struct tlista$$;
scan/#012ld34 5p67DNI$; //lush#stdin$;
scan/#0128[9:n]34 p67Nombre$; //lush#stdin$;
scan/#01;d34 5p67Edad$; //lush#stdin$;
p67psig % lista67psig; //El nue"o elemento apunta al
//=ue era el primer elemento
lista % p; //El nue"o elemento ahora es el primero
b* Insercin en cual&uier otro lu"ar, el ele$ento nue+o se coloca despu6s de
otro ya e%istente. .sta operacin re&uiere pri$ero encontrar el lu"ar donde se
3
(2)
(1)
desea insertar el ele$ento nue+o. Para ello se aplicar la operacin de
b2s&ueda &ue se co$entar $s adelante. Pode$os suponer a,ora &ue la
insercin se +a a realizar despu6s del ele$ento apuntado por un puntero q.
p .le$ento nue+o

55
lista
&
./.
//*e crea el nue"o elemento + se carga con datos,
p%#struct tlista *$malloc#-*si.eo/#struct tlista$$;
scan/#012ld34 5p67DNI$; //lush#stdin$;
scan/#0128[9:n]34 p67Nombre$; //lush#stdin$;
scan/#01;d34 5p67Edad$; //lush#stdin$;
p67psig % =67psig;
=67psig % p;
4 7ecorrer una lista enlazada. .sta operacin consiste en ir accediendo a cada
ele$ento de la lista de #or$a secuencial, por e/e$plo para ir +isualizando
todos los datos de la $is$a.
./. .l puntero lista apunta al inicio de la lista3
p % lista; //>omen.ar al principio de la lista
?hile #p @% N&''$
{
print/#012ld 125s 1;d34 p67DNI4p67Nombre4p67Edad$;
p % p67psig; //A"an.ar en una lista
!
4 8uscar un ele$ento de la lista a tra+6s de un ca$po. 9e e/ecutar un bucle
&ue #inaliza cuando se encuentre el +alor buscado o cuando #inalice la lista.
./. .n la lista de los e/e$plos anteriores, b2s&ueda a tra+6s de un :-I
tecleado3
scan/#012ld34 5DNIBuscado$;//lush#stdin$;
p % lista; //>omen.ar al principio de la lista
?hile #p67DNI @% DNIBuscado 55 p @% N&''$
p % p67psig; //A"an.ar en la lista
4
(1)
(2)
i/ #p @% N&''$ //DNI encontrado
print/#0Nombre,125s Edad,1;d34 p67Nombre4 p67Edad$;
else
print/#0DNI 12ld no est< en la lista34 DNIBuscado$;
//*i el elemento es encontrado4 =ueda apuntado por p
4 8orrar un ele$ento de la lista. Para saber &u6 ele$ento debe borrarse,
nor$al$ente se e/ecuta una b2s&ueda co$o se ,a e%plicado pre+ia$ente.
:eber e/ecutarse la #uncin free() y con ello liberar la $e$oria &ue ocupa el
ele$ento a eli$inar. .%isten dos +ariantes3
a* 8orrar el pri$er ele$ento de la lista. .l puntero al pri$er ele$ento de la
lista pasar a apuntar al se"undo ele$ento.
./. .l ele$ento a borrar est apuntado por p3
lista % lista67psig;
/ree#p$;
b* 8orrar un ele$ento distinto del pri$ero de la lista. .sta operacin a#ecta al
ele$ento anterior al &ue se +a a borrar, ya &ue ese ele$ento pasar a apuntar
al ele$ento si"uiente al &ue se +a a borrar. Para acceder a ese ele$ento
anterior, se debe tener un puntero apuntando al $is$o. Por ello, en el proceso
de b2s&ueda, la co$probacin del +alor &ue se busca se debe realizar sobre
el ele$ento si"uiente al &ue se +a recorriendo en dic,a b2s&ueda.
./. 8orrar el ele$ento cuyo :-I es tecleado3
scan/#012ld34 5DNIBuscado$;//lush#stdin$;
i/ #lista67DNI %% DNIBuscado$ //Borra primer elemento
{
p % lista;
lista % lista67psig;
/ree#p$;
!
else //*i no es el primer elemento,
{
p % lista; //>omen.ar al principio de la lista
//El bucle no comprueba el elemento p4 sino p-
>psig
?hile #p67psig67DNI @% DNIBuscado 55
p67psig @% N&''$
p % p67psig; //A"an.ar en la lista
i/ #p67psig @% N&''$ //DNI encontrado
{ //p apunta al anterior al elem a borrar
= % p67psig; //q apunta al elem a borrar
p67psig % p67psig67psig;
/ree#=$; //Elimina elemento
5
!
else
print/#0DNI 12ld no est< en lista34 DNIBuscado$;
!
3. Pilas.
(na pila es un caso particular de una lista enlazada en la &ue todas las
inserciones y supresiones se realizan sie$pre por el $is$o e%tre$o lista. 9e
suele lla$ar LI;< )Last Input ;irst <utput, la 2lti$a entrada es la pri$era
salida*.
.n un pila se $antiene el puntero apuntando al 2lti$o ele$ento
a0adido, el $s nue+o en la pila. .l pri$er ele$ento de la pila, el $s anti"uo,
$antiene su puntero con +alor -(LL. Cada ele$ento apunta el ele$ento
a0adido pre+ia$ente, es decir no apunta al si"uiente sino al anterior.
.le$.$s nue+o .le$. $s anti"uo
NULL
pila
9i el puntero pila de la #i"ura +ale -(LL indica &ue la pila est +aca.
!0adir o supri$ir un ele$ento i$plica actualizar ese puntero pila. Por e/e$plo,
para a0adir un nue+o ele$ento, 6ste debe apuntar al &ue estaba apuntado por
pila y pila apuntar a ese nue+o ele$ento.
p .le$ento nue+o

55
NULL
pila
4. Colas.
(na cola es un caso particular de una lista enlazada en la &ue todas las
inserciones se realizan por un e%tre$o de la lista y todas las supresiones se
realizan por el otro e%tre$o de la lista. 9e suele lla$ar ;I;< );irst Input ;irst
<utput, la pri$era entrada es la pri$era salida*.
9e suelen utilizar dos punteros, uno para cada e%tre$o de la cola para
&ue las operaciones sean $s rpidas. !$bos punteros +aldrn -(LL para
indicar &ue la cola est +aca. 9i a$bos punteros tienen el $is$o +alor y 6ste
no es -(LL, si"ni#ica &ue la cola slo tiene un ele$ento. Cada ele$ento
apuntar al si"uiente a0adido a la cola. .l ele$ento $s nue+o tendr su
puntero con el +alor -(LL, aun&ue esto no es necesario ya &ue al $antener
dos punteros, se puede reconocer en todo $o$ento cul es el pri$er y el
2lti$o ele$ento.
.le$. $s anti"uo .le$. $s nue+o
NULL
6
(2)
(1)
!nti"uo -ue+o
.n la #i"ura +e$os c$o el puntero Antiguo apunta al pri$er ele$ento
&ue se a0adi a la cola, al $s anti"uo. .l puntero Nuevo apunta al ele$ento
$s reciente a0adido a la cola, al $s nue+o. Para e%traer un ele$ento de la
cola, se debe actualizar el puntero Antiguo. Para a0adir un ele$ento a la cola
se debe actualizar el puntero Nuevo.
5. rboles. rboles binarios.
Las estructuras co$entadas pre+ia$ente son lineales, sin e$bar"o los
rboles son no lineales. (n rbol est #or$ado por una serie de ele$entos,
lla$ados nodos &ue se sit2an en di#erentes ni+eles. .%iste un nodo especial
&ue se deno$ina raz, por ser el inicio del rbol y por estar en el ni+el =. (n
puntero al nodo raz per$ite el acceso al rbol. !de$s de la in#or$acin &ue
se desee al$acenar, cada nodo incluir una serie de punteros para apuntar a
+arios ele$entos, &ue pertenecern al ni+el si"uiente del rbol. Los punteros
&ue no se utilicen en un $o$ento dado "uardarn el +alor -(LL. Cada
puntero en uso, &ue no +ale -(LL, de un nodo se lla$a ra$a. Los nodos &ue
no apuntan a nin"2n nodo del si"uiente ni+el se lla$an nodos ter$inales u
,o/as y tendrn el +alor -(LL en sus punteros. 9e puede decir &ue cada nodo
de un rbol es un nodo raz de un subrbol del rbol. Co$o un subrbol es
ta$bi6n un rbol, esta es una de#inicin recursi+a, &ue es un procedi$iento
&ue suele usarse en la pro"ra$acin de rboles.
rbol
ni+el = raz
ni+el 1
ni+el 2 nodo ter$inal
Co$o puede deducirse, un rbol slo puede recorrerse ,acia aba/o, ya
&ue no se utilizan punteros &ue apunten a nodos de ni+eles superiores,
sie$pre se apunta a ni+eles in#eriores. .sto &uiere decir &ue si a partir de un
nodo cual&uiera se recorre un subrbol, por e/e$plo el derec,o, y despu6s
partiendo de ese $is$o nodo se &uiere recorrer otro subrbol, por e/e$plo el
iz&uierdo, la direccin de dic,o nodo deber "uardarse, para poder retornar a
ese punto de partida despu6s de realizar el pri$er recorrido.
5.1. rboles binarios.
(n rbol binario es un caso particular de rbol en el &ue cada nodo
tiene dos punteros, con lo &ue podr apuntar co$o $%i$o a dos nodos del
ni+el si"uiente del rbol, es decir podr tener dos ra$as co$o $%i$o. Cada
nodo apunta a un subrbol iz&uierdo y un subrbol derec,o. Co$o un subrbol
es un rbol, se suelen aplicar $6todos recursi+os en su procesa$iento. La
#i"ura anterior es un rbol binario.
./.
7
struct tnodo{
long DNI;
char Nombre[25];
int Edad;
struct tnodo *pi.do; //Puntero a rama i.=uierda
struct tnodo *pdcho; //Puntero a rama derecha
!;
"oid main#"oid$
{
struct tnodo *arbol;//*er< el puntero al nodo ra(.
arbol % N&''; //De entrada4 el <rbol est< "ac(o

!
(n tipo especial de rbol binario es a&uel &ue est ordenado por un
deter$inado ca$po. 9uponiendo por e/e$plo &ue el ca$po de ordenacin es
el :-I, para &ue el rbol sea ordenado se aplica el si"uiente $6todo3 un nodo
se colocar apuntado por la iz&uierda del nodo superior )de ni+el superior* si
su :-I es $enor &ue el :-I del nodo superior> si el :-I es $ayor, se colocar
por la derec,a> este $6todo deber aplicarse para todos los nodos. .ste tipo
de rboles binarios se deno$ina rboles binarios de b2s&ueda, ya &ue la
b2s&ueda de un ele$ento cual&uiera es $uy rpida. .n estos rboles todos
los nodos del subrbol iz&uierdo tendrn un +alor )del ca$po de ordenacin*
$enor &ue el del nodo raz de ese subrbol, as co$o el subrbol derec,o
tendr nodos cuyo +alor ser $ayor &ue el del nodo raz de ese subrbol.
8
.?.7CICI<9 4 C!PI@(L< 133
7ealizar los si"uientes al"orit$os en pseudocdi"o y en C.
1. Aane/ar una lista enlazada con el si"uiente $en23 1.!0adir ele$ento>
2.8orrar ele$ento> 3.Consultar ele$ento> 4.;inalizar. !l #inalizar, "rabar
todos los ele$entos en un #ic,ero binario. Cada ele$ento tendr los datos
:-I, -o$bre y .dad.
2. Leer el #ic,ero anterior co$pleto y "rabarlo en una lista enlazada de #or$a
&ue &uede ordenada por :-I.
3. I$ple$entar una pila &ue per$ita realizar operaciones $ate$ticas a $odo
de calculadora en la &ue se ad$itan par6ntesis para dar prioridad a ciertas
operaciones sobre otras, por e/e$plo3 )3 B )5 C D* E 2* 5 4 C )5 C 3*.
4. I$ple$entar una cola para $antener las lla$adas &ue se +an ,aciendo con
un tel6#ono. Cada ele$ento "uardar el n2$ero al &ue se ,a lla$ado y la
duracin de la lla$ada. La cola tendr co$o $%i$o 2= lla$adas, de #or$a
&ue las nue+as lla$adas irn sobrescribiendo a las $s anti"uas. 9e debe
$ane/ar el si"uiente $en23 1.7ealizar lla$ada )se solicita el n2$ero y debe
contar el tie$po*> 2..li$inar lla$ada )slo se podr eli$inar la lla$ada $s
anti"ua*> 3.Consultar todas las lla$adas> 4.9alir.
5. (tilizando recursi+idad y un rbol binario de b2s&ueda )ordenado por :-I*,
$ane/ar el $en2 si"uiente3 1.!0adir ele$ento> 2.8orrar ele$ento>
3.Consultar ele$ento> 4.;inalizar> 5.9alir. Cada ele$ento tendr los datos
:-I, -o$bre y .dad.
9

You might also like