Hola,
para mi duda este es el codigo del programa:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ListaGenerica1
{
class ListaGenerica
{
class Nodo
{
public int info;
public Nodo sig;
}
private Nodo raiz;
public ListaGenerica()
{
raiz = null;
}
void Insertar(int pos, int x)
{
if (pos <= Cantidad() + 1)
{
Nodo nuevo = new Nodo();
nuevo.info = x;
if (pos == 1)
{
nuevo.sig = raiz;
raiz = nuevo;
}
else
if (pos == Cantidad() + 1)
{
Nodo reco = raiz;
while (reco.sig != null)
{
reco = reco.sig;
}
reco.sig = nuevo;
nuevo.sig = null;
}
else
{
Nodo reco = raiz;
for (int f = 1; f <= pos - 2; f++)
reco = reco.sig;
Nodo siguiente = reco.sig;
reco.sig = nuevo;
nuevo.sig = siguiente;
}
}
}
public int Extraer(int pos)
{
if (pos <= Cantidad())
{
int informacion;
if (pos == 1)
{
informacion = raiz.info;
raiz = raiz.sig;
}
else
{
Nodo reco;
reco = raiz;
for (int f = 1; f <= pos - 2; f++)
reco = reco.sig;
Nodo prox = reco.sig;
reco.sig = prox.sig;
informacion = prox.info;
}
return informacion;
}
else
return int.MaxValue;
}
public void Borrar(int pos)
{
if (pos <= Cantidad())
{
if (pos == 1)
{
raiz = raiz.sig;
}
else
{
Nodo reco;
reco = raiz;
for (int f = 1; f <= pos - 2; f++)
reco = reco.sig;
Nodo prox = reco.sig;
reco.sig = prox.sig;
}
}
}
public void Intercambiar(int pos1, int pos2)
{
if (pos1 <= Cantidad() && pos2 <= Cantidad())
{
Nodo reco1 = raiz;
for (int f = 1; f < pos1; f++)
reco1 = reco1.sig;
Nodo reco2 = raiz;
for (int f = 1; f < pos2; f++)
reco2 = reco2.sig;
int aux = reco1.info;
reco1.info = reco2.info;
reco2.info = aux;
}
}
public int Mayor()
{
if (!Vacia())
{
int may = raiz.info;
Nodo reco = raiz.sig;
while (reco != null)
{
if (reco.info > may)
may = reco.info;
reco = reco.sig;
}
return may;
}
else
return int.MaxValue;
}
public int PosMayor()
{
if (!Vacia())
{
int may = raiz.info;
int x = 1;
int pos = x;
Nodo reco = raiz.sig;
while (reco != null)
{
if (reco.info > may)
{
may = reco.info;
pos = x;
}
reco = reco.sig;
x++;
}
return pos;
}
else
return int.MaxValue;
}
public int Cantidad()
{
int cant = 0;
Nodo reco = raiz;
while (reco != null)
{
reco = reco.sig;
cant++;
}
return cant;
}
public bool Ordenada()
{
if (Cantidad() > 1)
{
Nodo reco1 = raiz;
Nodo reco2 = raiz.sig;
while (reco2 != null)
{
if (reco2.info < reco1.info)
{
return false;
}
reco2 = reco2.sig;
reco1 = reco1.sig;
}
}
return true;
}
public bool Existe(int x)
{
Nodo reco = raiz;
while (reco != null)
{
if (reco.info == x)
return true;
reco = reco.sig;
}
return false;
}
public bool Vacia()
{
if (raiz == null)
return true;
else
return false;
}
public void Imprimir()
{
Nodo reco = raiz;
while (reco != null) {
Console.Write (reco.info + "-");
reco = reco.sig;
}
Console.WriteLine();
}
static void Main(string[] args)
{
ListaGenerica lg=new ListaGenerica();
lg.Insertar (1, 10);
lg.Insertar (2, 20);
lg.Insertar (3, 30);
lg.Insertar (2, 15);
lg.Insertar (1, 115);
lg.Imprimir ();
Console.WriteLine ("Luego de Borrar el primero");
lg.Borrar (1);
lg.Imprimir ();
Console.WriteLine ("Luego de Extraer el segundo");
lg.Extraer (2);
lg.Imprimir ();
Console.WriteLine ("Luego de Intercambiar el primero con el tercero");
lg.Intercambiar (1, 3);
lg.Imprimir ();
if (lg.Existe(10))
Console.WriteLine("Se encuentra el 20 en la lista");
else
Console.WriteLine("No se encuentra el 20 en la lista");
Console.WriteLine("La posición del mayor es:"+lg.PosMayor());
if (lg.Ordenada())
Console.WriteLine("La lista está ordenada de menor a mayor");
else
Console.WriteLine("La lista no está ordenada de menor a mayor");
Console.ReadKey();
}
}
}
Bueno, al principio raiz apunta a null.
raiz = null;
Luego viene un nodo con la informacion 10.
lg.Insertar (1, 10);
Luego, el campo sig de este nodo apunta a raiz, que contiene null.
nuevo.sig = raiz;
Luego viene otro nodo con la informacion 20.
lg.Insertar (2, 20);
Luego el campo sig del nodo con la informacion 10 apunta al nodo con la informacion 20? Y con eso el nodo con la informacion 10 deja de apuntar al nodo raiz=null?
Nodo reco = raiz;
while (reco.sig != null)
{
reco = reco.sig;
}
reco.sig = nuevo;
nuevo.sig = null;
Que cosa entendi mal?
Gracias y saludos
You are not allowed to view links.
You are not allowed to view links.
Register or Login or You are not allowed to view links.
Register or Login
Bueno, al principio raiz apunta a null.
raiz = null;
Luego viene un nodo con la informacion 10.
lg.Insertar (1, 10);
Luego, el campo sig de este nodo apunta a raiz, que contiene null.
nuevo.sig = raiz;
Luego viene otro nodo con la informacion 20.
lg.Insertar (2, 20);
Luego el campo sig del nodo con la informacion 10 apunta al nodo con la informacion 20? Y con eso el nodo con la informacion 10 deja de apuntar al nodo raiz=null?
Nodo reco = raiz;
while (reco.sig != null)
{
reco = reco.sig;
}
reco.sig = nuevo;
nuevo.sig = null;
Tu lógica es correcta, como puedo ver el Nodo con info 10 ahora referencia al Nodo con info 20 en su campo sig. Y este último (el Nodo con info 20) referencia a null en su campo sig.
Saludos
Ahh vale, crei que entendi algo mal.
Y... otra preguntita:
Es aqui:
void Insertar(int pos, int x)
{
if (pos <= Cantidad() + 1)
{
Nodo nuevo = new Nodo();
nuevo.info = x;
if (pos == 1)
{
nuevo.sig = raiz;
raiz = nuevo;
}
else
if (pos == Cantidad() + 1)
{
Nodo reco = raiz;
while (reco.sig != null)
{
reco = reco.sig;
}
reco.sig = nuevo;
nuevo.sig = null;
}
else
{
Nodo reco = raiz;
for (int f = 1; f <= pos - 2; f++)
reco = reco.sig;
Nodo siguiente = reco.sig;
reco.sig = nuevo;
nuevo.sig = siguiente;
}
}
Aqui:
else
{
Nodo reco = raiz;
for (int f = 1; f <= pos - 2; f++)
reco = reco.sig;
Nodo siguiente = reco.sig;
reco.sig = nuevo;
nuevo.sig = siguiente;
}
Aqui:
for (int f = 1; f <= pos - 2; f++)
Solamente quiero saber si lo entendi bien:
Se ejecuta esta linea:
lg.Insertar (2, 15);
significa eso en la estructura repetitiva for que pos es 2? De ser el caso significa eso que la estrucutra repetitiva se repita mientras f sea menor o igual a 2 - 2, es decir 0? Pero de ser el caso la estructura repititiva for no podra dar vueltas porque f ya es 1.
Gracias y saludos
Es correcto,
el código es muy críptico, pero al final termina cumpliendo su propósito. Si invocas lg.Insertar(2, 15) logras colocar un Nodo en la posición 2.
Saludos
Hola grep,
de acuerdo con el codigo estamos en la posición tres. Pero si pos es dos entonces la estructura repetitiva for se veria asi:
for (int f = 1; f <= 2 - 2; f++)
Como ves, cambie el pos por un dos ya que pos es dos. F es uno. Entonces esta estructura repetitiva me quiere decir mientras 1 se menor a 0 se ejecutara esta estructura repetitiva. Pero 1 no es menor a 0; asi que estamos de acuerdo que esta estructura repetitiva no dara ni una sola vuelta? Y que esto, a su vez provocara que el nodo [2, 15] no se colocara en la posición dos?
Gracias y saludos
You are not allowed to view links.
You are not allowed to view links.
Register or Login or You are not allowed to view links.
Register or Login
de acuerdo con el codigo estamos en la posición tres. Pero si pos es dos entonces la estructura repetitiva for se veria asi:
for (int f = 1; f <= 2 - 2; f++)
Como ves, cambie el pos por un dos ya que pos es dos. F es uno. Entonces esta estructura repetitiva me quiere decir mientras 1 se menor a 0 se ejecutara esta estructura repetitiva. Pero 1 no es menor a 0; asi que estamos de acuerdo que esta estructura repetitiva no dara ni una sola vuelta?
Es correcto,
You are not allowed to view links.
You are not allowed to view links.
Register or Login or You are not allowed to view links.
Register or Login
Y que esto, a su vez provocara que el nodo [2, 15] no se colocara en la posición dos?
El nodo SI será colocado en la posición dos, osea después del nodo raiz, porque se ejecutará las sentencias que siguen.
Sabiendo que reco referencia al mismo lugar que raiz y que nuevo es el nuevo nodo con valor 15, entonces:
Nodo siguiente = reco.sig;
reco.sig = nuevo;
nuevo.sig = siguiente;
dá a entender que ya existía un nodo en la posición dos, pero ahora se desplazará a la posición tres mientras que el nuevo nodo estará en la posición dos.
Saludos
Citar
Sabiendo que reco referencia al mismo lugar que raiz
Pero si raiz es null entonces no tendra un campo sig.
Hay algo que no entiendo...
Analiza el contexto entero del método Insertar():
void Insertar(int pos, int x)
{
if (pos <= Cantidad() + 1) // Condicion primaria
{
Nodo nuevo = new Nodo();
nuevo.info = x;
if (pos == 1) // Condicion 1
{
...
}
else if (pos == Cantidad() + 1) // Condicion 2
{
...
}
else // Condicion 3
{
Nodo reco = raiz;
for (int f = 1; f <= pos - 2; f++)
reco = reco.sig;
Nodo siguiente = reco.sig;
reco.sig = nuevo;
nuevo.sig = siguiente;
}
}
}
Si ejecutas lg.Insertar (2, 15); sin antes haber insertado un nodo en la posición 1, entonces la Condición primaria no será verdadera por lo que no se insertará ningún nodo. Si raiz es null entonces esto es lo que sucede.
Pero si ejecutas lg.Insertar (2, 15); habiendo insertado antes un nodo en la posición 1, entonces la Condición primaria es verdadera y se ejecuta el bloque de la Condición 2.
Finalmente, si ejecutas lg.Insertar (2, 15); habiendo insertado antes más de un nodo, entonces se ejecuta el bloque de la Condición 3.
Saludos
Si; yo entiendo eso de las condiciones. Lo que me lía es no saber que es siguiente. Que es siguiente? Y que es reco.sig?
Estoy hablando de eso que viene después de la estructura repetitiva for en la condición 3.
Saludos
Por favor intenta leer atentamente y despacio, quizás te parezca un trabalenguas,
Nodo reco = raiz;
reco es una variable de referencia a instancias de tipo Nodo la cual es automáticamente inicializada para referenciar a la misma instancia a la que referencia raiz en ese momento.
Nodo siguiente = reco.sig;
siguiente es una variable de referencia a instancias de tipo Nodo (igual que reco) que es automáticamente inicializada para referenciar a la misma instancia a la que referencia el campo sig de la instancia referenciada por reco en ese momento.
Saludos
Ahhhhh; a ver... dejame saber si lo entendi:
Nodo siguiente = reco.sig;
siguiente fue inicializada para referenciar a la misma instancia a la que referencia el campo sig de la instancia referenciada por reco en ese momento. (Como tu dijiste).
reco.sig = nuevo;
El campo sig del nodo [3, 30] apunta a [2, 15].
nuevo.sig = siguiente;
El campo sig del nodo [2, 15] apunta al nodo [2, 20] porque siguiente apunta adonde apunta el campo sig de reco. Y el campo sig de reco apunta a [2, 20].
Correcto?
You are not allowed to view links.
You are not allowed to view links.
Register or Login or You are not allowed to view links.
Register or Login
reco.sig = nuevo;
El campo sig del nodo [3, 30] apunta a [2, 15].
reco referencia al nodo [1, 10].
En main tienes lo siguiente
ListaGenerica lg = new ListaGenerica();
lg.Insertar (1, 10);
lg.Insertar (2, 20);
lg.Insertar (3, 30);
lg.Insertar (2, 15);
.
.
.
La instancia de tipo ListaGenerica almacenará los nodos de la siguiente forma
+------------+ +-------------+ +------------+
| | | | | |
null<-----+nodo [3, 30]<----+ nodo [2, 20]<-----+nodo [1, 10]|
| | | | | |
+------------+ +-------------+ ^ +------------+
|
|
|
|
+
campo sig
Al ejecutar lg.Insertar(2, 15);, se crea un nuevo nodo y el mismo se coloca entre el nodo [1, 10] y el nodo [2, 20]. Observa como se ejecuta el siguiente bloque:
{
Nodo reco = raiz; // (1)
for (int f = 1; f <= pos - 2; f++) // (2)
reco = reco.sig;
Nodo siguiente = reco.sig; // (3)
reco.sig = nuevo; // (4)
nuevo.sig = siguiente; // (5)
}
(1) reco referencia a la misma instancia a la que referencia raiz. En este punto la instancia es el nodo [1, 10] el cual en su campo sig referencia al nodo [2, 20].
(2) la sentencia asociada al bucle no se ejecuta
(3) siguiente referencia a la misma instancia a la que referencia el campo sig de la instancia referenciada por reco. En este momento sig referencia al nodo [2, 20].
(4) ahora el campo sig del nodo [1, 10] referencia al nuevo nodo, osea el nodo [2, 15].
(5) ahora el campo sig del nuevo nodo [2, 15] referencia al nodo [2, 20].
Saludos
Huy...!! Muchisimas gracias. Que torpe!! No me habia dado cuenta.
Pero... si no te molestaria...: Tiene raiz un campo sig? Porque raiz es null.
Mira en esta parte:
public void Borrar(int pos)
{
if (pos <= Cantidad())
{
if (pos == 1)
{
raiz = raiz.sig;
}
else
{
Nodo reco;
reco = raiz;
for (int f = 1; f <= pos - 2; f++)
reco = reco.sig;
Nodo prox = reco.sig;
reco.sig = prox.sig;
}
}
}
Si tu invocas esta linea:
lg.Borrar (1);
Se ejecutara esta condición:
if (pos == 1)
{
raiz = raiz.sig;
}
Pero si raiz es null entonces no tendra un campo sig. O como es posible esto?
Gracias :)
You are not allowed to view links.
You are not allowed to view links.
Register or Login or You are not allowed to view links.
Register or Login
Tiene raiz un campo sig? Porque raiz es null.
La afirmación de que `raiz es null` no es del todo correcta. ¿En qué momento raiz referencia a null? es la pregunta que debes plantearte. En las respuestas anteriores he intentado aclarar que raiz no referencia a null.
You are not allowed to view links.
You are not allowed to view links.
Register or Login or You are not allowed to view links.
Register or Login
Si tu invocas esta linea:
lg.Borrar (1);
Se ejecutara esta condición:
if (pos == 1)
{
raiz = raiz.sig;
}
Pero si raiz es null entonces no tendra un campo sig. O como es posible esto?
En tu código tienes un solo caso en donde raiz referencia a null, y es cuando creas la instancia de ListaGenerica. Pero las sentencias siguientes insertan nodos, lo cual hace que raiz referencie siempre al primer nodo, entonces raiz no referencia a null.
El caso que planteas se puede reproducir, por ejemplo, de la siguiente manera:
static void Main(string[] args)
{
ListaGenerica lg = new ListaGenerica();
lg.Borrar(1);
}
Aquí raiz referencia a null y al ejecutar la sentencia raiz = raiz.sig; la máquina virtual del framework .NET produce una excepción de tipo System.NullReferenceException ya que null no tiene campo sig y al no existir código para el manejo de dicha excepción se finaliza la ejecución del programa.
Saludos
Ahhhhh, gracias; no me hubiera dado cuenta.
Te podria mostrar otra cosa? :)
El tema es el mismo. Solo el codigo cambia:
Citar
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ListaGenerica2
{
class ListaGenerica
{
class Nodo
{
public int info;
public Nodo sig;
}
private Nodo raiz;
public ListaGenerica()
{
raiz = null;
}
void InsertarPrimero(int x)
{
Nodo nuevo = new Nodo();
nuevo.info = x;
nuevo.sig = raiz;
raiz = nuevo;
}
public void InsertarUtlimo(int x)
{
Nodo nuevo = new Nodo();
nuevo.info = x;
if (raiz == null)
raiz = nuevo;
else
{
Nodo reco = raiz;
while (reco.sig != null)
{
reco = reco.sig;
}
reco.sig = nuevo;
}
}
public void InsertarSegundo(int x)
{
if (raiz != null)
{
Nodo nuevo = new Nodo();
nuevo.info = x;
if (raiz.sig == null)
{
//Hay un solo nodo.
raiz.sig = nuevo;
}
else
{
nuevo.sig = raiz.sig;
raiz.sig = nuevo;
}
}
}
public void InsertarAnteUltimo(int x)
{
if (raiz != null)
{
Nodo nuevo = new Nodo();
nuevo.info = x;
if (raiz.sig == null)
{
//Hay un solo nodo.
nuevo.sig = raiz;
raiz = nuevo;
}
else
{
Nodo atras = raiz;
Nodo reco = raiz.sig;
while (reco.sig != null)
{
atras = reco;
reco = reco.sig;
}
nuevo.sig = atras.sig;
atras.sig = nuevo;
}
}
}
public void BorrarPrimero()
{
if (raiz != null)
{
raiz = raiz.sig;
}
}
public void BorrarSegundo()
{
if (raiz != null)
{
if (raiz.sig != null)
{
Nodo tercero = raiz.sig;
tercero = tercero.sig;
raiz.sig = tercero;
}
}
}
public void BorrarUltimo()
{
if (raiz != null)
{
if (raiz.sig == null)
{
raiz = null;
}
else
{
Nodo reco = raiz.sig;
Nodo atras = reco;
while (reco.sig != null)
{
atras = reco;
reco = reco.sig;
}
atras.sig = null;
}
}
}
public void Imprimir()
{
Nodo reco = raiz;
while (reco != null)
{
Console.Write (reco.info + "-");
reco = reco.sig;
}
Console.WriteLine();
}
public void BorrarMayor()
{
if (raiz != null)
{
Nodo reco = raiz;
int may = raiz.info;
while (reco != null)
{
if (reco.info > may)
{
may = reco.info;
}
reco = reco.sig;
}
reco = raiz;
Nodo atras = raiz;
while (reco != null)
{
if (reco.info == may)
{
if (reco == raiz)
{
raiz = raiz.sig;
atras = raiz;
reco = raiz;
}
else
{
atras.sig = reco.sig;
reco = reco.sig;
}
}
else
{
atras = reco;
reco = reco.sig;
}
}
}
}
static void Main(string[] args)
{
ListaGenerica lg=new ListaGenerica();
lg.InsertarPrimero (10);
lg.InsertarPrimero(45);
lg.InsertarPrimero(23);
lg.InsertarPrimero(89);
lg.Imprimir();
Console.WriteLine("Insertamos un nodo al final:");
lg.InsertarUtlimo(160);
lg.Imprimir();
Console.WriteLine("Insertamos un nodo en la segunda posición:");
lg.InsertarSegundo(13);
lg.Imprimir();
Console.WriteLine("Insertamos un nodo en la anteultima posición:");
lg.InsertarAnteUltimo(600);
lg.Imprimir();
Console.WriteLine("Borramos el primer nodo de la lista:");
lg.BorrarPrimero();
lg.Imprimir();
Console.WriteLine("Borramos el segundo nodo de la lista:");
lg.BorrarSegundo();
lg.Imprimir();
Console.WriteLine("Borramos el ultimo nodo de la lista:");
lg.BorrarUltimo();
lg.Imprimir();
Console.WriteLine("Borramos el mayor de la lista:");
lg.BorrarMayor();
lg.Imprimir();
Console.ReadKey();
}
}
}
Mi duda estaba en este metodo:
Citar
void InsertarPrimero(int x)
{
Nodo nuevo = new Nodo();
nuevo.info = x;
nuevo.sig = raiz;
raiz = nuevo;
}
Y en este:
Citar
public void Imprimir()
{
Nodo reco = raiz;
while (reco != null)
{
Console.Write (reco.info + "-");
reco = reco.sig;
}
Console.WriteLine();
}
Bueno nosotros invocamos esto:
Citar
static void Main(string[] args)
{
ListaGenerica lg=new ListaGenerica();
lg.InsertarPrimero (10);
lg.InsertarPrimero(45);
lg.InsertarPrimero(23);
lg.InsertarPrimero(89);
lg.Imprimir();
Cuando invocamos el nodo 89 entonces raiz referenciara solamente 89?
De ser asi asi el metodo Imprimir solamente imprimira 89. Es asi esto?
Gracias y saludos
You are not allowed to view links.
You are not allowed to view links.
Register or Login or You are not allowed to view links.
Register or Login
Cuando invocamos el nodo 89 entonces raiz referenciara solamente 89?
raiz referenciará a una instacia de tipo Nodo con campo info igual a 89.
raiz no puede referenciar a un número. Observa el tipo de variable que es raiz.
You are not allowed to view links.
You are not allowed to view links.
Register or Login or You are not allowed to view links.
Register or Login
De ser asi asi el metodo Imprimir solamente imprimira 89. Es asi esto?
No. Imprimir() imprime todos los nodos insertados, separados por un guion, y en el orden inverso.
Saludos
Gracias amigazo. No hubiera entendido esto sin vos. :)