Ayuda con ejercicio de Algoritmo.

Iniciado por cEBH1994, 30 Mayo 2017, 02:39 AM

0 Miembros y 1 Visitante están viendo este tema.

cEBH1994

Buenas amigos soy nuevo en el foro espero me saquen de este apuro necesito construir el siguiente código en C++ y no entiendo mucho sobre nodos.

A través de la realización de un algoritmo en C++, deben de construir una Lista enlazada la cual tendrá los siguientes datos a insertar:


 cedula (int)

 nombre (string)

 apellido (string)

 edad (int)

 sexo (char)

Se debe de validar que la cédula que se ingrese en la lista sea mayor a 999999 y menor e igual a 99999999; ej: (N > 999999 && N <= 99999999). Esto debido a que las cédula solo pueden tener 7 u 8 dígitos. Dicha lista al ejecutarse debe realizar los siguientes métodos:

1. Insertar un registro al inicio de la lista.

2. Insertar un registro al final de la lista.

3. Contar la cantidad de registros que tiene la lista.

4. Buscar cualquier registro a través de la cédula dentro de la lista.

5. Recorrer la lista y mostrar todos sus registros.

6. Eliminar un registro al final de la lista.

7. Eliminar un registro en cualquier posición de la lista.

8. Vaciar o Destruir la lista.

Dicho ejercicio de listas enlazadas debe cumplir con los siguientes parámetros exigibles:

1. Tener un menú dinámico, el cual permita ejecutar cualquier método sin cerrarse el

programa.

2. Validar que las cédulas que se estén ingresando cumplan con la validación.

3. Tener una opción para salir del programa.

Espero poder obtener su ayuda o aporte saludos.

MCKSys Argentina

Hola!

Coloca el código que llevas hecho y plantea tus dudas puntuales. De esa forma podrás obtener una mejor ayuda.

Saludos!
MCKSys Argentina

"Si piensas que algo está bien sólo porque todo el mundo lo cree, no estás pensando."


cEBH1994

Gracias por la pronta respuesta el detalle esta en que no se como iniciar el código porque no entiendo muy bien sobre listas enlazadas y tampoco de nodos llevo días tratando pero la verdad no se y me mandaron ese ejercicio de proyecto final y necesito hacerlo si no raspo la materia me gustaría su ayuda y explicación.

engel lex

no tienes ni si quiera el main hecho? algo debes llevar... muestra que llevas y en que parte tienes la duda

recuerda, no se dan codigos listos, se resuelven dudas puntuales
El problema con la sociedad actualmente radica en que todos creen que tienen el derecho de tener una opinión, y que esa opinión sea validada por todos, cuando lo correcto es que todos tengan derecho a una opinión, siempre y cuando esa opinión pueda ser ignorada, cuestionada, e incluso ser sujeta a burla, particularmente cuando no tiene sentido alguno.

Serapis

#4
Cita de: cEBH1994 en 30 Mayo 2017, 04:47 AM
...el detalle esta en que no se como iniciar el código porque no entiendo muy bien sobre listas enlazadas y tampoco de nodos ...  ... ... y necesito hacerlo si no raspo la materia me gustaría su ayuda y explicación.
Bien, si no sabes por donde empezar... aunque creo que no te pedirían un ejercició del que no habeis dado el tema...

Una lista enlazada, es una lista 'encadenada', de hecho la traducción enlazada es esa, encadenada... exactamente como sucede con los eslabones de una cadena.
Esto quiere decir que cada 'nodo', tiene un puntero llamado siguiente que contiene la drección de memoria al siguiente 'nodo'.
Por nodo puede entenderse como un tipo de datos, una estructura por ejemplo, que contiene determinados datos relacionados entre sí, (como un registro).

A diferencia de los arrays, que tiene todos sus registros contiguos en la memoria, y por tanto sabiendo donde está el primero es fácil saber donde está el enésimo, una lista enlazada, puede tener sus registros, en cualquier posición d ela memoria y de hecho el único modo (partiendo solo de la propia lista), de saber donde se encuentra el enésimo nodo, es llegar justo al nodo anterior a ese enésimo, pués es quien contiene la dirección de ese registro (nodo).
Así un nodo se compone básiicamente de dos punteros:
A - El dato que contiene (o los datos, si guarda más de uno).
B - La dirección al siguiente nodo.

Así crear una lista enlazada, supone crear un nodo llamado raíz, al que siempre tenemos una referencia (por que al ser el nodo inicial, necesitamos saber su dirección, para poder acceder a los demás). Supone guardar el número de nodos que tiene, supone guardar el índice del nodo actual y una referencia al mismo. También una referencia al último nodo (para poder añadir tras él). Además supone crear como mínimo los métodos: AñadirNodo, EliminarNodo, VaciarLista, y por encima de ello Crearlista, Y EliminarLista... También será útil poder Recorrer la lista, o al menos poder acceder al nodo nº, y tampoco sobra una función BuscarNodo por un dato especñífico ni BuscarNodoSiguiente con el mismo dato a partir de un nodo dado (por ejemplo uno previo que contenía ese dato).
Al CrearLista, primero se crea el nodo raíz, en su dato puede quedar nulo o no, Según gustos, una forma típica es que el nodo raíz, no interfiere, no forma parte de la lista, así al crearse la lista, se establece Numnodos = 0, IndiceActual = -1 y se crea la referencia de nodo raíz.
Un nodo contiene dos elementos como te he señalado:
- Dato: del tipo de datos que interese
- Siguiente: puntero a otro nodo. si es el último, su valor es nulo.
Y puede haber una función para CrearNodo(Dato), que por lo general devuelve el puntero del nodo creado... así:
//Crear unalista enlazada cuando el nodo raíz no se usa en la propia lista.
Funcion CrearListaEnlazada
   Raiz = CrearNodo("")
   Ultimo = Raiz
   NumNodos =0
   IndiceActual = -1
   NodoActual = nulo
Fin Funcion


//Crear unalista enlazada cuando el nodo raíz se usa en la propia lista.
Funcion CrearListaEnlazada(String Dato) //más parámetros si se deben guardar más datos.
   Raiz = CrearNodo(Dato)
   Ultimo = Raiz
   NumNodos =1
   IndiceActual = 0
   NodoActual = Raiz
Fin Funcion


Funcion AñadirNodo(String Dato)
   Ultimo.Siguiente = CrearNodo(Dato) //Añade un nuevo nodo.
   NumNodos +=1
   Ultimo = Ultimo.Siguiente
Fin funcion


Una función que busca un nodo por el dato y devuelve el nodo. si no se encuentra devuelve nulo, porque el último nodo apunta como siguiente a nulo.
Nodo = Funcion BuscarNodo( String Dato)
   nodo n = raiz
   Mientras n.Dato != Dato
      n = n.Siguiente
   Fin mientras
   Devolver n  // si n es nulo, implica que se llego al final y no se encontró
Fin funcion


Una función que busca un nodo desde unaposición dada:
Nodo = Funcion BuscarNodoSiguiente(Nodo n, string Dato)
  Mientras n.Dato != Dato
      n = n.Siguiente
   Fin mientras
   Devolver n  // si n es nulo, implica que se llego al final y no se encontró
Fin funcion

Si se crea esta función la previa podría delegar en esta, para establecer como punto de búsqueda el nodo raíz.
Nodo = Funcion BuscarNodo( String Dato)
   Devolver BuscarNodoSiguiente(Raiz, Dato)  //
Fin funcion


Acceder al nodo enésimo.
Nodo = Funcion NodoIndice(Entero Indice)
  Si Indice < NumNodos luego //Numnodos siempre es 1 mayor que el indice mayor que puede ser pedido
      Si indice => Indice actual luego  // de dónde queda más cerca índice?
         n = NodoActual
         x = Indiceactual      
      Si no
         n = Raiz.Siguiente
         x = -1
   Si no
      Devolver nulo
   Fin si

   Mientras x< indice
        x +=1
        n = n.Siguiente
   Fin mientras  
   Si n.siguiente no es nulo luego
       IndiceActual = x
       NodoActual = n
   Fin si
   Devolver n
Fin funcion



// Inserta un nodo para que ocupela posición señalada.
Funcion InsertarNodo(Entero Posicion, String Dato)
  Si Posicion > NumNodos
      AñadirNodo(Dato) // Se añade al final si excede el número de nodos.
  Si no
       Nodo n = CrearNodo(dato)
      Si posicion <0
           Posicion = 0 // pasa a ser el primer nodo
      Fin si
      Nodo p = NodoIndice(Posicion-1) //lama a la función anterior, para darnos el nº nodo d ela lista.
      n.Siguiente = p.Siguiente
      p.siguiente = n
      NumNodos +=1    
     
      Si IndiceActual => Indice
          Indice +=1
      Fin si
  Fin si
Fin funcion


Una lista más robusta, es la doblemente enlazada, en la que hay además un puntero en cada nodo llamado Previo (o Anterior) y que apunta a un nodo anterior en vez de al Siguiente. Esto facilita el recorrido de la lista, hacia adelante o atrás. si la lista es simple (simplemente enlazada), entonces una busqueda debe ser siempre hacia adelante y si ni siquiera mantienes un 'NodoActual' y su 'indiceActual', entonces siempre deberás buscar desde la raiz. Un nodoActual e indiceActual, te permite decidir si es preferible buscar desde ahí hasta el final o desde la raiz hasta el actual.

Otra lista aún más completa, es cuando además es circular... es decir el último conecta al raíz, así puede buscarse desde el actual hacia adelante, y al final llegar al raíz para continuar hasta el actual. si es doblemente enlazada, igualmente desde Raíz habrá una conexión al último... En estos casos, al añadir un nodo, requiere reconectar el final con la raiz... Aunque sea circular, conviene reconocer cuando se pasa por el extremo, incluso aunque sea transparente al cliente...

Por último, si mantienes un actual recuerda que borrar un nodo intermedio, supone antes enlazar al siguiente al que ese a eliminar apunta, si no se perdería todos los que siguen tras él, y por supuesto actualizar 'indiceActual' si está por encima del que se elimina (baja una posición el índice)... del mismo modo que insertarnodo, actualiza el índice s está en la posición a insertar o más arriba...

en fin.... esto debe darte alguna idea y servirte de orientación... es algo rápido, así que tendrás que trabajarlo un poco y si decides que raiz, tenga importancia en la lista, debes ajustar el códig en consideración a ello. en la práctica es bueno que no forme parte de ello, porque funciones que requieren al menos un nodo, si la lista está vacía podría dar error, aunque siempre podrá controlarse de otro modo, es preciso decidirse y tenerlo en cuenta.

Ahora ya no tienes excusas, tu siguiente pregunta deberá aportar código si o si...

cEBH1994

#5
Gracias por la ayuda intentare realizar el código con el material que me facilito saludos.

cEBH1994

Logre un adelanto del código pero al tratar de correrlo me da el siguiente error quisiera me ayudaran el error que me indica es el siguiente.

collect2: error: ld returned 1 exit status


No se si me falta algo o tengo algo mal.

Código (cpp) [Seleccionar]
#include<iostream>
#include<stdlib.h>
using namespace std;

struct Registro{
int cedula;
string nombre;
string apellido;
int edad;
char sexo;
Registro *Rpersona;
};


void menu();
void insertarLista(Registro *&,int c, string n, string a, int e, char s);
void mostrarLista(Registro *);
void buscarLista(Registro *,int c);
void eliminarNodo(Registro *&,int c);
void eliminarLista(Registro *&,int &);

Registro *lista = NULL;

int main(){

menu();

return 0;
}

void menu(){
int opcion,c,e;
string n,a;
char s;


do{
cout<<"\t.:::Proyecto UBV:::.\n";
cout<<"1. Ingresar un Registro a la lista\n";
cout<<"2. Mostrar los Registros de la lista\n";
cout<<"3. Buscar un Registro en la lista\n";
cout<<"4. Eliminar un Registro de la lista\n";
cout<<"5. Dejar vacia la lista\n";
cout<<"6. Salir\n";
cout<<"Opcion: ";
cin>>opcion;

switch(opcion){
case 1: cout<<"\nIngrese un Numero de Cedula: ";
        cin>>c;
                    cout<<"\nIngrese el Nombre: ";
cin>>n;
cout<<"\nIngrese el Apellido: ";
cin>>a;
cout<<"\nIngrese la Edad: ";
cin>>e;
cout<<"\nIngrese el Sexo: ";
cin>>s;
insertarLista(lista,c,n,a,e,s);
cout<<"\n";
system("pause");
break;
case 2: mostrarLista(lista);
cout<<"\n";                         
system("pause");
break;
case 3: cout<<"\nIngrese el Numero de Cedula a Buscar en el Registro: ";
cin>>c;
buscarLista(lista,c);
cout<<"\n";
system("pause");
break;
case 4: cout<<"\nIngrese el Numero de Cedula a Eliminar del Registro: ";
cin>>c;
eliminarNodo(lista,c);
cout<<"\n";
system("pause");
break;
case 5:
while(lista != NULL){
eliminarLista(lista,c);
cout<<c <<" -> ";
}
cout<<"\n";
system("pause");
break;
}
system("cls");
}while(opcion != 6);
}

void insertarLista(Registro *&,int c, string n, string a, int e, char s){
Registro *nuevo_registro = new Registro();

nuevo_registro->cedula = c;
nuevo_registro->nombre = n;
nuevo_registro->apellido = a;
nuevo_registro->edad = e;
nuevo_registro->sexo = s;
Registro *aux1 = lista;
Registro *aux2;

while((aux1 != NULL) && (aux1->cedula < c), (aux1->nombre < n), (aux1->apellido < a), (aux1->edad < e), (aux1->sexo < s)){
aux2 = aux1;
aux1 = aux1->Rpersona;
}

if(lista == aux1){
lista = nuevo_registro;
}
else{
aux2->Rpersona = nuevo_registro;
}

nuevo_registro->Rpersona = aux1;

cout<<"\tPersona "<<c<<" insertada a la lista correctamente\n";
}

void mostrarLista(Registro *lista){
Registro *actual = new Registro();
actual = lista;

while(actual != NULL){
cout<<actual->cedula<<" -> ";
cout<<actual->nombre<<" -> ";
cout<<actual->apellido<<" -> ";
cout<<actual->edad<<" -> ";
cout<<actual->sexo<<" -> ";
actual = actual->Rpersona;
}
}

void buscarLista(Registro *lista,int c,string n,string a,int e,char s){
bool band = false;

Registro *actual = new Registro();
actual = lista;

while((actual != NULL) && (actual->cedula <= c), (actual->nombre <= n), (actual->apellido <= a),(actual->edad <= e), (actual->sexo <= s)){
if((actual->cedula == c), (actual->nombre == n), (actual->apellido == a), (actual->edad == e), (actual->sexo == s)){
band = true;
}
actual = actual->Rpersona;
}

if(band == true){
cout<<"Persona "<<n<<" SI a sido encontrado en lista\n";
}
else{
cout<<"Persona "<<n<<" NO a sido encontrado en la lista\n";
}
}

void eliminarNodo(Registro *&lista,int c,string n, string a, int e, char s){

if(lista != NULL){
Registro *aux_borrar;
Registro *anterior = NULL;

aux_borrar = lista;


while((aux_borrar != NULL) && (aux_borrar->cedula != c), (aux_borrar->nombre != n), (aux_borrar->apellido != a), (aux_borrar->edad != e), (aux_borrar->sexo != s)){
anterior = aux_borrar;
aux_borrar = aux_borrar->Rpersona;
}


if(aux_borrar == NULL){
cout<<"La persona no ha sido encontrado";
}

else if(anterior == NULL){
lista = lista->Rpersona;
delete aux_borrar;
}

else {
        anterior->Rpersona = aux_borrar->Rpersona;
delete aux_borrar;
}
}
}

       
        void eliminarLista(Registro *&lista,int &c, string &n, string &a,int &e, char &s){
    Registro *aux = lista;
    c = aux->cedula;
    n = aux->nombre;
    a = aux->apellido;
    e = aux->edad;
    s = aux->sexo;
    lista = aux->Rpersona;
    delete aux;
}