listas enlazadas simples

Iniciado por dmon1, 13 Abril 2015, 01:56 AM

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

dmon1

Por favor podrian ayudarme con este codigo?
Lo saque de un libro pero no compila, son listas enlazadas simples
No encuentro el error. Gracias!!

Código (cpp) [Seleccionar]
#include <stdio.h>
#include <stdlib.h>

struct listNode{
char data;
struct listNode *nextPtr;
};
typedef struct listNode LISTNODE;
typedef LISTNODE *LISTNODEPTR;

void insert(LISTNODEPTR *, char);
char deleter(LISTNODEPTR *, char);
int isEmpty(LISTNODEPTR);
void printList(LISTNODEPTR);
void instruccions(void);

main()
{
LISTNODEPTR startPtr = NULL;
int choice;
char item;

instruccions();
printf("?");
scanf("%d",&choice);

while (choice!= 3)
{
switch (choice)
{
case 1:
printf("enter a character");
scanf("n%c", &item);
insert(&startPtr, item);
printList(startPtr);
break;
case 2:
if (!isEmpty(startPtr))
{
printf("enter character to be deleted");
scanf("\n%c", &item);

if (deleter(&startPtr, item))
{
printf("%c deleted", item);
printList(startPtr);
}
else
{
printf("%c not found\n", item);
}
}
else
{
printf("List is empty\n");
}
break;
default:         //si la opcion es invalida le vuelve a preguntar
printf("invalid choice \n");
instruccions();
break;
}
printf("?");
scanf("%d", &choice);
}
printf("end of run\n");
return 0;
}

void instruccions(void) //mostrar opciones
{
printf("enter your choice:\n"
"1 to insert an element into the list\n"
"2 to delete an element from the list\n"
"3 to end\n");
}

void insert(LISTNODEPTR *sPtr, char value)
{
LISTNODEPTR newPtr, previousPtr, currentPtr;

newPtr =(LISTNODEPTR) malloc(sizeof(LISTNODE));

if (newPtr != NULL)
{
newPtr->data = value;
newPtr->nextPtr = NULL;

previousPtr = NULL;
currentPtr = *sPtr;

while (currentPtr != NULL&&value > currentPtr->data)
{
previousPtr = currentPtr;
currentPtr = currentPtr->nextPtr;
}

if (previousPtr == NULL)
{
newPtr->nextPtr = *sPtr;
*sPtr = newPtr;
}
else
{
previousPtr->nextPtr = newPtr;
newPtr->nextPtr = currentPtr;
}
}
else
{
printf("%c not inserted no memmory avalaible\n", value);
}



char deleter(LISTNODEPTR *sPtr, char value)
{
LISTNODEPTR tempPtr, previousPtr, currentPtr;

if (value == (*sPtr)->data)
{
tempPtr = *sPtr;
*sPtr = (*sPtr)->nextPtr;
free(tempPtr);
return value;
}
else
{
previousPtr = *sPtr;
currentPtr = (*sPtr)->nextPtr;

while (currentPtr != NULL&&currentPtr->data != value)
{
previousPtr = currentPtr;
currentPtr = currentPtr->NextPtr;
}
if (currentPtr != NULL)
{
tempPtr = currentPtr;
previousPtr->nextPtr = currentPtr->nextPtr;
free (tempPtr);
return value;
}
}
return 0;
}

int isEmpty(LISTNODEPTR sPtr)
{
return sPtr == NULL;
}

void printList(LISTNODEPTR currentPtr)
{
if (currentPtr == NULL)

printf("List is empty");

else
{
printf("the list is:");
while (currentPtr != NULL)
{
printf("%c --> ", currentPtr->data);
currentPtr = currentPtr->nextPtr;
}
printf("NULL \n\n");
}
}



Mod: modificado el código con etiquetas GeSHi,

DarK_FirefoX

1ro - Utiliza las etiquetas GeSHi si vas a publicar código
2do- Podrías dar un poco de información sobre el error, no somos adivinos

dmon1

1- Es mi primer post, no tenia idea de las GeShi
2- Es una lista enlazada que a partir de una eleccion (switch) ejecuta una u otra funcion
3- El error es este: fatal error LNK1169: one or more multiply defined symbols found
Solo encontre que faltaba cerrar la llave en la declaracion de la funcion Insert.
Gracias

DarK_FirefoX

Cita de: danimontero en 13 Abril 2015, 03:30 AM
1- Es mi primer post, no tenia idea de las GeShi

Pasate por aquí ;) http://foro.elhacker.net/reglas.htm

PD: Estoy revisando

dmon1

Gracias!!

Rindo ese tema en pocos días y tengo que demostrar que funcionan bien las opciones.

eferion

#5
Línea 33: scanf ( "n%c", &item ); <<-- debería ser \n

Línea 136: currentPtr = currentPtr->NextPtr; <-- esa 'n' debería ir en minúsculas

Código (cpp) [Seleccionar]

 instruccions();
 scanf ( "%d", &choice );

 while ( choice != 3 )
 {
   // ...

   printf ( "?" );
   scanf( "%d", &choice );
 }


Por qué actualizar "choice" en dos sitios diferentes??

si usas "do-while" en vez de "while" puedes eliminar uno de los usos... además, sería recomendable poner las instrucciones siempre salvo que pretendas que el usuario se las apunte nada más arrancar el programa:

Código (cpp) [Seleccionar]

 do
 {
   instruccions();
   scanf ( "\n%d", &choice );

   // ...
 } while ( choice != 3 );


Claro, ahora tienes que añadir al "switch" un "case 3" para evitar mostrar las instrucciones al salir:

Código (cpp) [Seleccionar]

     case 3:
       break;
       
     default:         //si la opcion es invalida le vuelve a preguntar
       printf ( "invalid choice \n" );
       //instruccions(); <<-- Esto también sobra ya
       break;


Luego, no se si te has dado cuenta, pero los elementos los estás insertando al inicio de la lista... no al final, no se si esa parte la tienes que programar así, aunque me da que no.

y bueno, luego te toca arreglar algun detalle relacionado con la forma de presentar los mensajes... pero eso ya corre de tu cuenta.

Ah bueno, sí, se me olvidaba jejeje. No estás liberando la memoria reservada por la lista una vez finalizas el programa... deberías plantearte corregir eso también.

Un saludo

dmon1

Muchas gracias! Ahora si logra compilar  :D

Lo que no logro resolver es borrar elementos luego de insertarlos, es eso posible?
Es decir que si elijo "case 1" me deja insertarlos pero si despues quisiera borrarlos, como deberia hacerlo?

Falta la ultima parte de liberar memoria, voy a averiguar como se hace por que no me lo explicaron

Sorry por las GESHI, no logro cambiarles el color

Asi me quedo el codigo:

#include <stdio.h>
#include <stdlib.h>

typedef struct listNode{
   char data;
   struct listNode *nextPtr;
}LISTNODE;

typedef LISTNODE *LISTNODEPTR;

void insert(LISTNODEPTR *, char);
char deleter(LISTNODEPTR *, char);
void printList(LISTNODEPTR);
int isEmpty(LISTNODEPTR);
void instruccions(void);

main()
{
   LISTNODEPTR startPtr = NULL;
   char choice;
   char item;

   instruccions();
   scanf("%d", &choice);

   do
   {
      switch (choice)
      {
      case 1:
         printf("enter a character\n");
         scanf("%c\n", &item);
         insert(&startPtr, item);
         printList(startPtr);
         break;
      case 2:
         if (!isEmpty(startPtr))
         {
            printf("enter character to be deleted");
            scanf(" %c\n", &item);

            if (deleter(&startPtr, item))
            {
               printf("%c deleted", item);
               printList(startPtr);
            }
            else
            {
               printf("%c not found\n", item);
            }
         }
         else
         {
            printf("List is empty\n");
         }
         break;

      case 3:
         printf("invalid choice \n");
      default:         //si la opcion es invalida le vuelve a preguntar
         printf("invalid choice \n");
         break;
      }
   }
   
   while (choice != 3);
   return 0;
}

void instruccions(void) //mostrar opciones
{
   printf("enter your choice:\n"
      "1 to insert an element into the list\n"
      "2 to delete an element from the list\n"
      "3 to end\n");
}

void insert(LISTNODEPTR *sPtr, char value)
{
   LISTNODEPTR newPtr, previousPtr, currentPtr;

   newPtr = (LISTNODEPTR)malloc(sizeof(LISTNODE));

   if (newPtr != NULL)
   {
      newPtr->data = value;
      newPtr->nextPtr = NULL;

      previousPtr = NULL;
      currentPtr = *sPtr;

      while (currentPtr != NULL&&value > currentPtr->data)
      {
         previousPtr = currentPtr;
         currentPtr = currentPtr->nextPtr;
      }

      if (previousPtr == NULL)
      {
         newPtr->nextPtr = *sPtr;
         *sPtr = newPtr;
      }
      else
      {
         previousPtr->nextPtr = newPtr;
         newPtr->nextPtr = currentPtr;
      }
   }
   else
   {
      printf("%c not inserted no memmory avalaible\n", value);
   }

}
char deleter(LISTNODEPTR *sPtr, char value)
{
   LISTNODEPTR tempPtr, previousPtr, currentPtr;

   if (value == (*sPtr)->data)
   {
      tempPtr = *sPtr;
      *sPtr = (*sPtr)->nextPtr;
      free(tempPtr);
      return value;
   }
   else
   {
      previousPtr = *sPtr;
      currentPtr = (*sPtr)->nextPtr;

      while (currentPtr != NULL&&currentPtr->data != value)
      {
         previousPtr = currentPtr;
         currentPtr = currentPtr->nextPtr;
      }
      if (currentPtr != NULL)
      {
         tempPtr = currentPtr;
         previousPtr->nextPtr = currentPtr->nextPtr;
         free(tempPtr);
         return value;
      }
   }
   return 0;
}

int isEmpty(LISTNODEPTR sPtr)
{
   return sPtr == NULL;
}

void printList(LISTNODEPTR currentPtr)
{
   if (currentPtr == NULL)

      printf("List is empty");

   else
   {
      printf("the list is:");
      while (currentPtr != NULL)
      {
         printf("%c --> ", currentPtr->data);
         currentPtr = currentPtr->nextPtr;
      }
      printf("NULL \n\n");
   }
}

eferion

Las GeSHi te explico: Habrás notado que, al escribir un mensaje, tienes una serie de botones encima del TextBox para, por ejemplo, poner el texto en negrita, cursiva o subrayado, elegir la alineación del texto, etc... uno de esos controles es un ComboBox con el texto GeSHi. Si despliegas esa lista verás que aparece el nombre de varios lenguajes de programación... elijes el que corresponda y te añadirá un par de etiquetas (una de apertura y otra de cierre) a tu mensaje... pon el código entre medias y listo. También funciona si pones el código, lo seleccionas y luego elijes el idioma en el desplegable.

Para borrar un elemento de una lista tienes 3 posibilidades:

1. El elemento a borrar es el primero. Tienes que hacer que el puntero de inicio de la lista pase al siguiente elemento:
A -> B -> C -> NULL ==> B -> C -> NULL

2. El elemento a borrar es el último. Simplemente pones a NULL el puntero "sig" del penúltimo elemento:
A -> B -> C -> NULL ==> A -> B -> NULL

3. El elemento está en el medio de la lista. En este caso tienes que hacer que el puntero "sig" del elemento anterior apunte al elemento que sigue al actual:
A -> B -> C -> NULL ==> A -> C -> NULL

En cualquiera de los tres casos no te olvides de liberar la memoria del elemento recién liberado.

Para liberar la memoria reservada por un malloc (o calloc o realloc) tienes que usar la función free:


// Reserva de memoria
int* ptr = (int*)malloc( 100 *sizeof( int ) );

// Se libera la memoria. Vuelve a estar disponible
free( ptr );


Un saludo

dmon1

Genial !!

Muchas gracias por la ayuda, dejo el código completo funcionando perfectamente.

Ahora voy a tratar de implementarlo para una lista doblemente enlazada. Cualquier cosa, hago otro post.

Saludos :)


#include <stdio.h>
#include <stdlib.h>

typedef struct listNode{
char data;
struct listNode *nextPtr;
}LISTNODE;

typedef LISTNODE *LISTNODEPTR;

void insert(LISTNODEPTR *, char);
char deleter(LISTNODEPTR *, char);
void printList(LISTNODEPTR);
int isEmpty(LISTNODEPTR);
void instruccions(void);

int main()
{
LISTNODEPTR startPtr = NULL;
char choice, item;

instruccions();
fflush(stdin);
scanf("%c", &choice);

while (choice != '3')
{
switch (choice)
{
case '1':
printf("Ingrese un elemento a la lista\n");
fflush(stdin);
scanf("%c", &item);
insert(&startPtr, item);
printList(startPtr);
break;
case '2':
if (!isEmpty(startPtr))
{
printf("Escriba el elemento que quiera eliminar\n");
fflush(stdin);
scanf("%c", &item);

if (deleter(&startPtr, item))
{
printf("El elemento %c fue eliminado\n", item);
printList(startPtr);
}
else
{
printf("%c Elemento no encontrado\n\n", item);
}
}
else
{
printf("La lista está vacia\n");
}
break;

default:         //si la opcion es invalida le vuelve a preguntar
printf("Opcion invalida \n");
break;
}

instruccions();
fflush(stdin);
scanf("%c", &choice);

}

printf("FIN DEL PROGRAMA");

return 0;
}

void instruccions(void) //mostrar opciones
{
printf("Elija su opcion:\n"
"1 Para insertar un elemento en la lista\n"
"2 Para eliminar un elemento de la lista \n"
"3 Para cerrar el programa\n");
}

void insert(LISTNODEPTR *sPtr, char value)
{
LISTNODEPTR currentPtr, previousPtr, newPtr;
currentPtr = *sPtr;
previousPtr = NULL;
while (currentPtr != NULL&&currentPtr->data<value)
{
previousPtr = currentPtr;
currentPtr = currentPtr->nextPtr;
}
newPtr = (LISTNODEPTR)malloc(sizeof(LISTNODE));
newPtr->data = value;
newPtr->nextPtr = currentPtr;
if (previousPtr != NULL)
{
previousPtr->nextPtr = newPtr;
}
else
{
*sPtr = newPtr;
}

}
char deleter(LISTNODEPTR *sPtr, char value)
{
LISTNODEPTR tempPtr, previousPtr, currentPtr;

if (value == (*sPtr)->data)
{
tempPtr = *sPtr;
*sPtr = (*sPtr)->nextPtr;
free(tempPtr);
return value;
}
else
{
previousPtr = *sPtr;
currentPtr = (*sPtr)->nextPtr;

while (currentPtr != NULL&&currentPtr->data != value)
{
previousPtr = currentPtr;
currentPtr = currentPtr->nextPtr;
}
if (currentPtr != NULL)
{
tempPtr = currentPtr;
previousPtr->nextPtr = currentPtr->nextPtr;
free(tempPtr);
return value;
}
}
return 0;
}

int isEmpty(LISTNODEPTR sPtr)
{
return sPtr == NULL;
}

void printList(LISTNODEPTR currentPtr)
{
if (currentPtr == NULL)

printf("La lista esta vacia\n\n");

else
{
printf("LA LISTA ES:\n");
while (currentPtr != NULL)
{
printf(" %c-->", currentPtr->data);
currentPtr = currentPtr->nextPtr;
}
printf("NULL \n\n");
}
}