Buenas profe, queria saber si lo que desarrolle seria correcto:
2_ a_
typedef struct treg{
int num;
bool prim;
int dig;
};
typedef struct tnodo *pnodo;
typedef struct tnodo {
treg dato;
pnodo ant;
pnodo sig;
};
//si vas a usar un único puntero establecer un registro tlista es incorrecto, sólo se usa un registro si tienes al menos 2 campos que representan la lista, como un puntero y un contador por ejemplo, eso hace que debas cambiar las operaciones
typedef struct tlista
pnodo inicio;
};
main(){
tlista lista; //aquí debería ser directamente pnodo lista, ya que sólo tiene un puntero no corresponde el registro
pnodo nuevo;
}
b_
void agregar_final(tlista &lista, pnodo nuevo){ //debes trabajar con pnodo &lista
pnodo i;
if(lista.inicio==NULL){
lista.inicio=nuevo;
}else{
for(i=lista.inicio;i->sig!=NULL;i=i->sig);
if(nuevo->dato.num==i->dato.num-1 && nuevo->dato.prim==true){//cuál es el objetivo de la condición que está en azul?
si por ejemplo el último nodo fuese 7 y el nuevo valor 13 preguntaría 13==8 (incluso provoca error y permite guardar 2 primos de manera consecutiva)
cout<<"No se puede agregar, no cumple con lo requerido"<<endl;
delete(nuevo);
}else{
i->sig=nuevo;
nuevo->ant=i;
}
}
}
c_
pnodo mayor_primo(tlista lista){//debes trabajar con pnodo
pnodo mayor,i;
if(lista.inicio==NULL)
mayor=NULL;
else{
mayor=lista.inicio;
for(i=lista.inicio->sig;i!=NULL;i=i->sig){ //la lógica es correcta, pero debes trabajar con pnodo y no con tlista
if((i->dato.num > mayor->dato.num) && i->dato.prim==true)
mayor=i;
}
}
return mayor;
}
d_válido, se podría optimizar si consideras que el parámetro de opción lo recibe el módulo que muestra y en base a eso realiza el recorrido que corresponde.
void submenu(char &op){
cout<<"***Menu***"<<endl;
cout<<"1_Inicio"<<endl;
cout<<"2_Final"<<endl;
cout<<"Elija una opcion"<<endl;
cin>>op;
}
void mostrar_lista_op(tlista lista){
char op;
if(lista.inicio != NULL){
submenu(op);
switch(op){
case '1': mostrar_lista1(lista);
break;
case '2': mostrar_lista2(lista);
break;
}
}else
cout<<"LISTA VACIA";
}
void mostrar_lista1(tlista lista){
pnodo i;
for(i=lista.inicio;i!=NULL;i=i->sig)
if(i->dato.prim==true)
cout<<"Nodo: "<<i->dato.num<<" dig: "<<i->dato.dig<<" Es Primo"<<endl;
else
cout<<"Nodo: "<<i->dato.num<<" dig: "<<i->dato.dig<<" NO es Primo"<<endl;
}
void mostrar_lista2(tlista lista){
pnodo i,j;
for(i=lista.inicio;i->sig!=NULL;i=i->sig);
for(j=i;j!=NULL;j=j->ant)
cout<<"Nodo: "<<j->dato.num<<endl;
}
3_a_válido
const int MAX=10;
typedef struct tnodo *pnodo;
typedef struct tnodo {
char dato;
pnodo ant;
pnodo sig;
};
typedef struct tlista{
pnodo inicio;
pnodo fin;
int cont;
};
main(){
tlista lista;
pnodo nuevo;
}
b_//válido
void agregar_final(tlista &lista, pnodo nuevo){
if(lista.cont!=MAX){
if(lista.inicio==NULL){
lista.inicio=nuevo;
lista.fin=nuevo;
}else{
lista.fin->sig=nuevo;
nuevo->ant=lista.fin;
lista.fin=nuevo;
}
lista.cont++;
}else{
cout<<"No se puede agregar mas nodos"<<endl;
delete(nuevo);
}
}
4_a_
typedef struct tnodo *pnodo;
typedef struct tnodo {
int dato;
pnodo ant;
pnodo sig;
};
typedef struct tlista{//no debe usarse un registro para un único campo, se debería trabajar directamente con pnodo
cuidado!!, esto obliga a cambiar todas las operaciones para considerarse correctas
pnodo inicio;
};
main(){
tlista lista,lista2,lista3; deberías se pnodo y no tlista
}
b_ //aquí deberías tener una operación que cargue una lista y luego invocarla 2 a fin de no repetir código
void agregar(tlista &lista, tlista &lista2){
char resp;
int valor;
pnodo nuevo;
cout<<"Lista 1"<<endl;
do{
cout<<"Ingrese valor: ";
cin>>valor;
crear_nodo(nuevo,valor);
if(nuevo!=NULL)
agregar_orden(lista,nuevo);
else
cout<<"Memoria Llena"<<endl;
cout<<"Desea agregar otro valor (s/n)? : ";
cin>>resp;
} while(resp!='n');
cout<<"Lista 2"<<endl;
do{
cout<<"Ingrese valor: ";
cin>>valor;
crear_nodo(nuevo,valor);
if(nuevo!=NULL)
agregar_orden(lista2,nuevo);
else
cout<<"Memoria Llena"<<endl;
cout<<"Desea agregar otro valor (s/n)? : ";
cin>>resp;
} while(resp!='n');
}
void agregar_orden(tlista &lista, pnodo nuevo){//debes adaptar a una lista de tipo pnodo
pnodo i;
if(lista.inicio==NULL){
lista.inicio=nuevo;
}else{
if(nuevo->dato <= lista.inicio->dato){
nuevo->sig=lista.inicio;
lista.inicio->ant=nuevo;
lista.inicio=nuevo;
}else{
for(i=lista.inicio;i->sig!=NULL && (i->sig)->dato < nuevo->dato;i=i->sig);
if(i->sig==NULL){
i->sig=nuevo;
nuevo->ant=i;
}else{
nuevo->sig=i->sig;
nuevo->ant=i;
(i->sig)->ant=nuevo;
i->sig=nuevo;
}
}
}
}
(cargar valores aleatorios)//aquí la carga también debería hacerse por separada cada lista, un módulo de carga invocado dos veces
void agregar(tlista &lista, tlista &lista2){
int valor,cant;
pnodo nuevo;
cout<<"Lista 1"<<endl;
cout<<"Indique la cantidad a ingresar: ";
cin>>cant;
do{
valor=rand()%90+10;
crear_nodo(nuevo,valor);
if(nuevo!=NULL)
agregar_orden(lista,nuevo);
else
cout<<"Memoria Llena"<<endl;
cant--;
} while(cant>0);
cout<<"Lista 2"<<endl;
cout<<"Indique la cantidad a ingresar: ";
cin>>cant;
do{
valor=rand()%90+10;
crear_nodo(nuevo,valor);
if(nuevo!=NULL)
agregar_orden(lista2,nuevo);
else
cout<<"Memoria Llena"<<endl;
cant--;
} while(cant>0);
}
5_a_
typedef struct tnodo *pnodo;
typedef struct tnodo {
int dato;
pnodo ant;
pnodo sig;
};
typedef struct tlista{//no corresponde si sólo se tiene un puntero
pnodo inicio;
};
main(){
tlista lista;debería ser pnodo y no tlista
pnodo nuevo;
}
b_
void agregar_orden(tlista &lista, pnodo nuevo){l//lista debería ser pnodo
pnodo i;
if(lista.inicio==NULL){
lista.inicio=nuevo;
lista.inicio->sig=lista.inicio;
lista.inicio->ant=lista.inicio;
}else{
if(nuevo->dato <= lista.inicio->dato){
nuevo->sig=lista.inicio;
lista.inicio->ant=nuevo;
for(i=lista.inicio;i->sig!=lista.inicio;i=i->sig);
nuevo->ant=i;
i->sig=nuevo;
lista.inicio=nuevo;
}else{
for(i=lista.inicio;i->sig!=lista.inicio && (i->sig)->dato < nuevo->dato;i=i->sig);
if(i->sig==lista.inicio){//estos casos podrían unificarse al tratarse de una lista doble circular con un único puntero
i->sig=nuevo;
nuevo->ant=i;
nuevo->sig=lista.inicio;
lista.inicio->ant=nuevo;
}else{ //este intercambio de punteros sirve para cuando se agrega en medio o al final para este planteo
nuevo->sig=i->sig;//si fuese al final este engancha el nuevo con el inicio
nuevo->ant=i; //este el nuevo con el último
(i->sig)->ant=nuevo;//el inicio con el nuevo
i->sig=nuevo;//el final con el nuevo
}
}
}
}
pnodo quitar_nodo_espe(tlista &lista, int borrado){//debes trabajar con pnodo para lista
pnodo i, extraido;
if(lista.inicio==NULL)
extraido=NULL;
else{
if(lista.inicio->dato==borrado){
if(lista.inicio->sig==lista.inicio){
extraido=lista.inicio;
lista.inicio=NULL;
extraido->sig=NULL;
extraido->ant=NULL;
}else{
for(i=lista.inicio;i->sig!=lista.inicio;i=i->sig);
extraido=lista.inicio;
lista.inicio=extraido->sig;
i->sig=lista.inicio;
i->ant=lista.inicio;//este debería ser inicio->ant=i;
extraido->sig=NULL;
extraido->ant=NULL;
}
}else{
for(i=lista.inicio;i->sig!=lista.inicio && (i->sig)->dato != borrado; i=i->sig);
if((i->sig)->dato==borrado){
extraido=i->sig;
i->sig=extraido->sig;
(extraido->sig)->ant=i;
extraido->sig=NULL;
extraido->ant=NULL;
}else
extraido=NULL;
}
}
return extraido;
}
bool buscar_nodo(tlista lista, int valor){
bool encontrado=false;
pnodo i;
for(i=lista.inicio;i->sig!=lista.inicio && valor>i->dato && encontrado==false;i=i->sig);//esto funciona si la lista está ordenada, si no podría preguntar por != en lugar de mayor
if(valor==i->dato)
encontrado=true;
return encontrado;
}
c_//válida la lógica pero debe trabajar con lista de tipo pnodo ya que la definición no es válida
int contar_nodo_impar(pnodo list, tlista lista){
int c;
if(list->sig==lista.inicio)
c=0;
else{
if((list->dato)%2!=0)
c=1+contar_nodo_impar(list->sig,lista);
else
c=contar_nodo_impar(list->sig,lista);
}
return c;
}
símil al anterior, lógica válida pero debe corregir la definición de la estructura para que se considere el ejercicio
int sumar_nodos(pnodo i, tlista lista){
if(i->sig==lista.inicio)
return i->dato;
else
return i->dato + sumar_nodos(i->sig,lista);
}
void mostrar_lista(tlista lista,pnodo n, char op1){debe trabajar con pnodo lista
if(lista.inicio == NULL)
cout<<"Lista vacia"<<endl;
else{
if(n->sig==lista.inicio)
cout<<n->dato<<endl;
else{
if(op1=='1'){
cout<<n->dato<<endl;
mostrar_lista(lista,n->sig,op1);
}else{
if(op1=='2'){
mostrar_lista(lista,n->sig,op1);
cout<<n->dato<<endl;
}
}
}
}
}
6_ (circulares)
void agregar_inicio(tlista &lista, pnodo nuevo){//circular
if(lista.contador!=MAX){
if(lista.inicio==NULL){
lista.inicio=nuevo;
lista.fin=nuevo;
}else{
nuevo->vecino[0]=lista.inicio;//recomendación siempre marcar la consideración que tienen posición 0 siguiente, posición 1 anterior por ejemplo
lista.inicio->vecino[1]=nuevo;
lista.inicio=nuevo;
}
lista.fin->vecino[0]=lista.inicio;
lista.inicio->vecino[1]=lista.fin;
lista.contador++;
}else{
cout<<"Superaste el limite"<<endl;
delete(nuevo);
}
}
pnodo quitar_final(tlista &lista){ //circular
pnodo extraido;
if(lista.inicio==NULL){
extraido=NULL;
}else{
extraido=lista.fin;
if(lista.inicio==lista.fin){
iniciar_lista(lista);
}else{
lista.fin=lista.fin->vecino[1];//apunta al anterior considerando que 1 es ant
lista.inicio->vecino[1]=lista.fin;
lista.fin->vecino[0]=lista.inicio;
lista.contador--;
}
extraido->vecino[0]=NULL;
extraido->vecino[1]=NULL;
}
return extraido;
}
void mostrar_lista(tlista lista){válido
pnodo i;
if(lista.contador==0)
cout<<"Lista Vacia"<<endl;
else{
i=lista.inicio;
while(i->vecino[0]!=lista.inicio){
cout<< i->dato <<endl;
i=i->vecino[0];
}
cout<< i->dato <<endl;
}
}
Saludos
(Editado por Verónica Torres - envío original viernes, 8 de septiembre de 2023, 00:41)