Listas vinculadas
pascal:
Uses Crt;
Type PRec = ^Rec;
Rec = Record
Num: Integer;
Next: PRec;
End;
Procedure Insertar(Var Prim: PRec; Elem: Integer);
Var L: PRec;
Begin
If Prim = Nil Then {¨No tiene elementos?}
Begin
New(Prim);
Prim^.Num:= Elem;
Prim^.Next:= Nil;
End Else {S¡ los tiene}
Begin
L:= Prim; {Me voy al primer elemento}
While L^.Next <> Nil Do {Me desplazo hasta encontrar un nodo sin "siguiente"}
L:= L^.Next;
New(L^.Next); {Alojo memoria para el nuevo nodo "siguiente"}
L:= L^.Next; {Entro al nodo nuevo}
L^.Num:= Elem; {Escribo el valor a insertar en el nodo nuevo}
L^.Next:= Nil; {Establezco como "Nil" al siguiente del nodo nuevo}
End;
End;
Procedure Mostrar(L: PRec);
Var Cont: Integer;
Begin
Cont:= 0;
While L <> Nil Do
Begin
Inc(Cont);
WriteLn('El elemento ',cont,' es: ',L^.Num);
L:= L^.Next;
End;
End;
Procedure Eliminar(Var Prim: PRec; Elem: Integer);
Var L,Prev: PRec;
Seguir: Boolean;
Begin
Prev:= Nil;
If Prim <> Nil Then {La idea es eliminar solo si la lista tiene algun elemento}
Begin
L:= Prim;
Seguir:= True;
While Seguir Do
Begin
If L^.Num = Elem Then {¨Encontr‚ el elemento?}
Begin
{Elimina un nodo liberando su memoria y corrigiendo la lista.
No es la pr ctica m s recomendable ya que hace que quede fragmentada
la memoria de trabajo (Heap), pero servir para entender la idea,
aunque mejor ser¡a que en el momento de eliminar los datos el programa
corra los datos que le siguen al nodo a eliminar "uno para adelante"
y finalmente eliminar el ultimo nodo}
If L = Prim Then {Es el primero?}
Begin {Si, libero la memoria del primer nodo y establezco como primero al que sigue.}
Prim:= L^.Next;
Dispose(L);
Seguir:= False;
End Else {No es el primero}
Begin
Prev^.Next:= L^.Next; {El siguiente del anterior ser el siguiente del nodo a eliminar}
Dispose(L); {Libero la memoria del nodo a eliminar}
Seguir:= False;
End;
End;
Prev:= L;
L:= L^.Next;
If L = Nil Then Seguir:= False;
End;
End;
End;
{Igual que "Eliminar" pero a la hora de borrar mueve los datos de los nodos
y libera la memoria del £ltimo nodo
*Recomendado para evitar la fragmentacion de la memoria*}
Procedure Eliminar_2(Var Prim: PRec; Elem: Integer);
Var L,Prev: PRec;
Seguir: Boolean;
Begin
Prev:= Nil;
If Prim <> Nil Then {La idea es eliminar solo si la lista tiene algun elemento}
Begin
L:= Prim;
Seguir:= True;
While Seguir Do
Begin
If L^.Num = Elem Then {¨Encontr‚ el elemento?}
Begin
While L^.Next <> Nil Do
Begin
L^.Num:= L^.Next^.Num;
Prev:= L;
L:= L^.Next;
End;
If L = Prim Then
Begin
Dispose(Prim);
Prim:= Nil;
End Else
Begin
Dispose(L);
Prev^.Next:= Nil;
End;
Seguir:= False;
End Else
Begin
Prev:= L;
L:= L^.Next;
If L = Nil Then Seguir:= False;
End;
End;
End;
End;
{Ordena los elementos de la lista simple, utilizando m‚todo de selecci¢n
(Por ser el m s facil para ordenar). Para ordenar los elementos solo
muevo los datos sin tocar los nodos.}
Procedure Ordenar(Var Prim: PRec);
Var L,L2: PRec;
Inter: Integer;
Begin
L:= Prim;
While L <> Nil Do
Begin
L2:= L^.Next;
While L2 <> Nil Do
Begin
If L^.Num > L2^.Num Then
Begin
Inter:= L^.Num;
L^.Num:= L2^.Num;
L2^.Num:= Inter;
End;
L2:= L2^.Next;
End;
L:= L^.Next;
End;
End;
Var Prim: PRec;
C: Char;
Num: Integer;
Begin
Prim:= Nil;
C:= '1';
While C <> '4' Do
Begin
ClrScr;
Mostrar(Prim);
WriteLn;
WriteLn('1- Insertar elemento');
WriteLn('2- Eliminar');
WriteLn('3- Ordenar');
WriteLn('4- Salir');
WriteLn;
C:= ReadKey;
If C = '1' Then
Begin
Write('Ingrese el valor a insertar: ');
ReadLn(Num);
Insertar(Prim,Num);
End;
If C = '2' Then
Begin
Write('Ingrese el valor que desea eliminar: ');
ReadLn(Num);
Eliminar(Prim,Num);
End;
If C = '3' Then Ordenar(Prim);
End;
End.
Type PRec = ^Rec;
Rec = Record
Num: Integer;
Next: PRec;
End;
Procedure Insertar(Var Prim: PRec; Elem: Integer);
Var L: PRec;
Begin
If Prim = Nil Then {¨No tiene elementos?}
Begin
New(Prim);
Prim^.Num:= Elem;
Prim^.Next:= Nil;
End Else {S¡ los tiene}
Begin
L:= Prim; {Me voy al primer elemento}
While L^.Next <> Nil Do {Me desplazo hasta encontrar un nodo sin "siguiente"}
L:= L^.Next;
New(L^.Next); {Alojo memoria para el nuevo nodo "siguiente"}
L:= L^.Next; {Entro al nodo nuevo}
L^.Num:= Elem; {Escribo el valor a insertar en el nodo nuevo}
L^.Next:= Nil; {Establezco como "Nil" al siguiente del nodo nuevo}
End;
End;
Procedure Mostrar(L: PRec);
Var Cont: Integer;
Begin
Cont:= 0;
While L <> Nil Do
Begin
Inc(Cont);
WriteLn('El elemento ',cont,' es: ',L^.Num);
L:= L^.Next;
End;
End;
Procedure Eliminar(Var Prim: PRec; Elem: Integer);
Var L,Prev: PRec;
Seguir: Boolean;
Begin
Prev:= Nil;
If Prim <> Nil Then {La idea es eliminar solo si la lista tiene algun elemento}
Begin
L:= Prim;
Seguir:= True;
While Seguir Do
Begin
If L^.Num = Elem Then {¨Encontr‚ el elemento?}
Begin
{Elimina un nodo liberando su memoria y corrigiendo la lista.
No es la pr ctica m s recomendable ya que hace que quede fragmentada
la memoria de trabajo (Heap), pero servir para entender la idea,
aunque mejor ser¡a que en el momento de eliminar los datos el programa
corra los datos que le siguen al nodo a eliminar "uno para adelante"
y finalmente eliminar el ultimo nodo}
If L = Prim Then {Es el primero?}
Begin {Si, libero la memoria del primer nodo y establezco como primero al que sigue.}
Prim:= L^.Next;
Dispose(L);
Seguir:= False;
End Else {No es el primero}
Begin
Prev^.Next:= L^.Next; {El siguiente del anterior ser el siguiente del nodo a eliminar}
Dispose(L); {Libero la memoria del nodo a eliminar}
Seguir:= False;
End;
End;
Prev:= L;
L:= L^.Next;
If L = Nil Then Seguir:= False;
End;
End;
End;
{Igual que "Eliminar" pero a la hora de borrar mueve los datos de los nodos
y libera la memoria del £ltimo nodo
*Recomendado para evitar la fragmentacion de la memoria*}
Procedure Eliminar_2(Var Prim: PRec; Elem: Integer);
Var L,Prev: PRec;
Seguir: Boolean;
Begin
Prev:= Nil;
If Prim <> Nil Then {La idea es eliminar solo si la lista tiene algun elemento}
Begin
L:= Prim;
Seguir:= True;
While Seguir Do
Begin
If L^.Num = Elem Then {¨Encontr‚ el elemento?}
Begin
While L^.Next <> Nil Do
Begin
L^.Num:= L^.Next^.Num;
Prev:= L;
L:= L^.Next;
End;
If L = Prim Then
Begin
Dispose(Prim);
Prim:= Nil;
End Else
Begin
Dispose(L);
Prev^.Next:= Nil;
End;
Seguir:= False;
End Else
Begin
Prev:= L;
L:= L^.Next;
If L = Nil Then Seguir:= False;
End;
End;
End;
End;
{Ordena los elementos de la lista simple, utilizando m‚todo de selecci¢n
(Por ser el m s facil para ordenar). Para ordenar los elementos solo
muevo los datos sin tocar los nodos.}
Procedure Ordenar(Var Prim: PRec);
Var L,L2: PRec;
Inter: Integer;
Begin
L:= Prim;
While L <> Nil Do
Begin
L2:= L^.Next;
While L2 <> Nil Do
Begin
If L^.Num > L2^.Num Then
Begin
Inter:= L^.Num;
L^.Num:= L2^.Num;
L2^.Num:= Inter;
End;
L2:= L2^.Next;
End;
L:= L^.Next;
End;
End;
Var Prim: PRec;
C: Char;
Num: Integer;
Begin
Prim:= Nil;
C:= '1';
While C <> '4' Do
Begin
ClrScr;
Mostrar(Prim);
WriteLn;
WriteLn('1- Insertar elemento');
WriteLn('2- Eliminar');
WriteLn('3- Ordenar');
WriteLn('4- Salir');
WriteLn;
C:= ReadKey;
If C = '1' Then
Begin
Write('Ingrese el valor a insertar: ');
ReadLn(Num);
Insertar(Prim,Num);
End;
If C = '2' Then
Begin
Write('Ingrese el valor que desea eliminar: ');
ReadLn(Num);
Eliminar(Prim,Num);
End;
If C = '3' Then Ordenar(Prim);
End;
End.