2

Tengo el siguiente código para trabajar con colas. ¿Cómo se podrían contar y modificar los elementos de la cola en el siguiente código?

#include<iostream>
#include<conio.h>
#include<stdlib.h>
using namespace std;

struct Nodo{
  char dato;
  Nodo *siguiente;  
};

//Prototipos de Funciones
void menu();
void insertarCola(Nodo *&,Nodo *&,char);
bool cola_vacia(Nodo *);
void suprimirCola(Nodo *&,Nodo *&,char &);

int main(){

  menu();

  getch();
  return 0;
}

void menu(){
  int opc;
  char dato;

  Nodo *frente = NULL;
  Nodo *fin = NULL;

  do{
    printf("Menu\n");
    printf("Insertar un caracter a una cola");
    printf("Mostrar todos los elementos de la cola");
    printf("Salir");
    printf("opcion");
    scanf("%d",&opc);
    switch(opc){
        case 1: printf("\nIngrese el caracter para agregar a la cola: ");
                scanf("%d",&dato);
                insertarCola(frente,fin,dato);
                break;
        case 2: printf("\nMostrando los elementos de la cola: ");
                while(frente != NULL){
                    suprimirCola(frente,fin,dato);
                    if(frente != NULL){
                        cout<<dato<<" , ";
                    }
                    else{
                        cout<<dato<<".";
                    }
                }
                printf("\n");
                system("pause");
                break;
        case 3: break;
    }
    system("cls");
  }while(opc != 3);
}

//Función para insertar elementos en la cola
void insertarCola(Nodo *&frente,Nodo *&fin,char n){
  Nodo *nuevo_nodo = new Nodo();

  nuevo_nodo->dato = n;
  nuevo_nodo->siguiente = NULL;

  if(cola_vacia(frente)){
    frente = nuevo_nodo;
  }
  else{
    fin->siguiente = nuevo_nodo;
  }

  fin = nuevo_nodo;
}

//Función para determinar si la cola está vacia
bool cola_vacia(Nodo *frente){
  return (frente == NULL)? true : false; 
}

//Función para eliminar elementos de la cola
void suprimirCola(Nodo *&frente,Nodo *&fin,char &n){
  n = frente->dato;
  Nodo *aux = frente;

  if(frente == fin){
    frente = NULL;
    fin = NULL;
  }
  else{
    frente = frente->siguiente;
  }
  delete aux;
}
Alvaro Montoro
  • 48,157
  • 26
  • 100
  • 179
Laura
  • 65
  • 1
  • 7
  • Hola Laura, las preguntas que son sólo código se consideran de baja calidad. Sería ideal que añadieras más información sobre qué hace el código, cómo funciona y qué has intentado. Además, has marcado la pregunta como C, pero parece que realmente estás usando C++, ¿podrías confirmarlo? Lee [ask] y cómo crear un [mcve] donde encontrarás recomendaciones para mejorar tus preguntas. – Alvaro Montoro Sep 11 '18 at 02:26
  • @Laura Hola, veo que has modificado tu pregunta, e incluso la has movido de C a C++, entonces, publiqué dos respuesta, una donde podrás encontrar la respuesta en C y otra en C++, podrías aclararme cual es la que realmente requieres, así podré eliminar una de las dos para evitar la redundancia (por el momento dejaré ambas hasta que respondas). La próxima vez te aconsejo revisar tu preguntar antes de publicarla para que puedas obtener mejores respuestas (justo como ya te dijeron en un comentario anterior). – codenoschool Sep 11 '18 at 03:30

3 Answers3

1

Dado que has etiquetado la pregunta como C++, deberías usar el lenguaje correctamente:

  • La cabecera <stdlib.h> es de no de . Las cabeceras de C disponen de una versión adaptada a C++ que tiene el prefijo c y carece de extensión. Si realmente necesitas usar las cabeceras de C (que nunca será el caso) debes usar el equivalente de C++ <cstdlib> . Lee este hilo para saber por qué.
    • De todas formas, no estás usando nada de <cstdlib> así que no necesitas incluirla.
  • La cabecera <conio.h> ni siquera es estándar C y no existe en C++, lee este hilo para saber por qué.
  • No hay obligación de usar la cláusula using namespace std; pues es sólo es una ayuda a la escritura de código; si decides usar esta cláusula no lo hagas en el ámbito global, úsala en el ámbito más pequeño posible. Lee este hilo para saber por qué.
  • printf y scanf son las funciones de lectura de consola de C, en C++ se usan los objetos stream: std::cout y std::cin.

Ahora, tus preguntas:

¿Cómo se podrían contar los elementos de la cola?

Según puedo ver, estás desarrollando una lista simplemente enlazada lo que implica que cada nodo apunta a su siguiente nodo; también observo que es una lista abierta dado que el último nodo apunta a NULL por lo tanto la manera más sencilla de contar los elementos de la cola es recorrerlos uno a uno e ir sumando su número:

int contar(const Nodo *&inicio)
{
    int resultado = 0;

    for (auto i = inicio; i; i = i->siguiente)
        ++resultado;

    return resultado;
}

¿Cómo se podrían modificar los elementos de la cola?

Para modificar un elemento, tendrás que localizarlo ¿De qué manera? ¿Por índice? ¿Por valor?. Asumo que es por índice ya que por valor pueden haber duplicados, deberás crear una función de búsqueda:

Nodo *busca(const Nodo *&inicio, int indice)
{
    Nodo *nodo = inicio;

    for (int i= 0; (i < indice) && nodo; ++i)
        nodo = nodo->siguiente;

    return nodo;
}

Una vez has encontrado el nodo, puedes cambiar su valor:

auto tercero = busca(tu_nodo, 3);
tercero->dato = nuevo_valor;
PaperBirdMaster
  • 44,474
  • 6
  • 44
  • 82
0

Preparé el siguiente código como respuesta, y hace solamente y precisamente lo que pides en tu pregunta: Cuenta el número de elementos que hay en la lista y puede modificar los elementos que hay dentro*.

*Como no especificaste si deseabas modificarlos por indice o por búsqueda de carácter incluí las dos formas (por favor, incluye más detalles la próxima vez).

Y aquí está el código. **

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

typedef struct node {
    char data;
    struct node *next;
} node_t;

void print_list(node_t *);
void count_list_elements(node_t *);
void modify_an_item_by_index(node_t *, int, char);
void modify_an_item_by_char(node_t *, char, char);

int main(void) {
    int i;
    char u;
    char data;

    node_t *head = NULL;
    head = (node_t *)malloc(sizeof(node_t));

    head->data = 'a';
    head->next = (node_t *)malloc(sizeof(node_t));
    head->next->data = 'e';
    head->next->next = NULL;
    printf("List: \n");
    print_list(head);
    printf("Ingresa el indice del elemento a modificar (comienza desde 0): ");
    scanf("%d", &i);
    printf("Ingresa el nuevo valor: ");
    scanf(" %c", &data);
    modify_an_item_by_index(head, i, data);
    printf("Ingresa el caracter a buscar: ");
    scanf(" %c", &u);
    printf("Ingresa el nuevo valor: ");
    scanf(" %c", &data);
    modify_an_item_by_char(head, u, data);
    printf("New List: \n");
    print_list(head);
    count_list_elements(head);

    return 0;
}

void print_list(node_t *head) {
    node_t *current = head;

    while (current != NULL) {
        printf("%c\n", current->data);
        current = current->next;
    }
}

void count_list_elements(node_t *head) {
    node_t *current = head;
    int n = 0;

    while (current != NULL) {
        current = current->next;
        n += 1;
    }

    printf("La lista tiene %d elementos.\n", n);
}

void modify_an_item_by_index(node_t *head, int i, char new_data) {
    node_t *current = head;

    int x;

    for(x = 0; x < i; x++) {
        current = current->next;
    }

    current->data = new_data;
}

void modify_an_item_by_char(node_t *head, char i, char new_data) {
    node_t *current = head;

    while (current != NULL) {
        if (current->data == i) {
            break;
        }
        current = current->next;
    }

    current->data = new_data;
}

** Respondí a esta pregunta cuando estaba en la sección de C, después el autor o alguien más lo cambió a C++. Añadí otra respuesta en C++ para este pregunta (búscala).

El output (resultado de ejecución) del programa al pasar algunos parámetros, es el siguiente:

List:
a
e
Ingresa el indice del elemento a modificar (comienza desde 0): 0
Ingresa el nuevo valor: o
Ingresa el caracter a buscar: e
Ingresa el nuevo valor: u
New List:
o
u
La lista tiene 2 elementos.

Una nota más: El código hace solamente lo que pediste, las validaciones son todas tuyas (para evitar comportamiento inadecuado), ya que no las incluí porque el código se complicaría y podría ser complicado entender lo que de verdad necesitas como respuesta.

codenoschool
  • 171
  • 1
  • 1
  • 10
0

Este es el código en el lenguaje a C++ que preparé y que realiza lo que solicitas en tu pregunta: Contar los elementos de la lista, y poder acceder a los elementos para modificarlos, ya sea por su índice o buscando un carácter.

Código:

#include <iostream>

typedef struct node {
    char data;
    struct node *next;
} node_t;

void print_list(node_t *);
void count_list_elements(node_t *);
void modify_an_item_by_index(node_t *, int, char);
void modify_an_item_by_char(node_t *head, char i, char new_data);

int main(void) {
    int i;
    char u;
    char data;

    node_t *head = NULL;
    head = new node_t();

    head->data = 'a';
    head->next = new node_t();
    head->next->data = 'e';
    head->next->next = NULL;
    std::cout << "List: " << std::endl;
    print_list(head);
    std::cout << "Ingresa el indice del elemento a modificar (comienza desde 0): ";
    std::cin >> i;
    std::cout << "Ingresa el nuevo valor: ";
    std::cin >> data;
    modify_an_item_by_index(head, i, data);
    std::cout << "Ingresa el caracter a buscar: ";
    std::cin >> u;
    std::cout << "Ingresa el nuevo valor: ";
    std::cin >> data;
    modify_an_item_by_char(head, u, data);
    print_list(head);
    count_list_elements(head);

    return 0;
}

void print_list(node_t *head) {
    node_t *current = head;

    while (current != NULL) {
        std::cout << current->data << std::endl;
        current = current->next;
    }
}

void count_list_elements(node_t *head) {
    node_t *current = head;
    int n = 0;

    while (current != NULL) {
        current = current->next;
        n += 1;
    }

    std::cout << "La lista tiene " << n << " elementos." << std::endl;
}

void modify_an_item_by_index(node_t *head, int i, char new_data) {
    node_t *current = head;

    for(int x = 0; x < i; x++) {
        current = current->next;
    }

    current->data = new_data;
}

void modify_an_item_by_char(node_t *head, char i, char new_data) {
    node_t *current = head;

    while (current != NULL) {
        if (current->data == i) {
            break;
        }
        current = current->next;
    }

    current->data = new_data;
}

Breve explicación: Observa como en las funciones que se encargan de modificar los valores de un nodo primero se crea un apuntador a nodo llamado current y es una copia del apuntador a nodo head, se hace de esta manera para no perder la cabeza de la lista head, y con current poder recorrer los nodos hasta encontrar el nodo con el índice o carácter indicado (depende de cual de las dos funciones utilices). Una vez identificado el nodo, ya podemos acceder a sus valores y modificarlos con el valor que se desee.

En cuanto a contar los nodos, tenemos algo muy parecido al anterior pero mucho más sencillo ya que solamente necesitas recorrer la lista de nodos mediante el apuntador a nodo current (que es una copia de head) y almacenar las iteraciones dentro de una variable para después mostrarla en pantalla.

A la hora de ejecutar el programa y pasar algunos parámetros se obtiene el siguiente output/resultado:

List:
a
e
Ingresa el indice del elemento a modificar (comienza desde 0): 0
Ingresa el nuevo valor: o
Ingresa el caracter a buscar: e
Ingresa el nuevo valor: u
o
u
La lista tiene 2 elementos.

Nota: Las validaciones para evitar comportamiento inadecuado son todas tuyas. No las incluí pues podría complicar la compresión de la respuesta a tu pregunta.

codenoschool
  • 171
  • 1
  • 1
  • 10