0
votes

Problèmes de pointeur de liste liée simple (et d'erreur)

Je suis un Noob, j'ai du mal avec le C, les pointeurs et les listes chaînées (enfin, tout vraiment). J'essaie de créer une liste chaînée très simple de listes liées, mais je reçois des messages d'erreur indiquant que le `` type de base de référence de membre '' struct node * 'n'est pas une structure ou une union. Ayant lutté pendant un certain temps, je me rends compte que le suivant dans votre liste de listes peut à la fois pointer vers l'élément de liste suivant aux deux endroits, mais je ne sais pas si j'ai besoin de 2 types de nœuds, ou quelle est la meilleure façon de le faire.

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

// node that can hold char * (strings) and next
struct node {
    char* data;
    struct node * next;
};

/*
I'm trying to create a linked list (containing List 1 and List 2) of linked lists, i.e.

    List 1         List 2
    1A               2A
    1B               2B

Where only nodes 1A, 1B, 2A and 2B have unique data (List 1 data just pointers to 1A data, List1 next just points to 1A next etc.)
*/

int main()
{

    // Will contain pointers to the heads of the 2 linked lists
    struct node** list_1 = NULL;
    struct node** list_2 = NULL;

    // Nodes under list_1
    struct node* one_a = NULL;
    struct node* one_b = NULL;

    // Nodes under linked list b
    struct node* two_a = NULL;
    struct node* two_b = NULL;

    // allocate 6 nodes in the heap
    list_1 = (struct node**)malloc(sizeof(struct node*));
    list_2 = (struct node**)malloc(sizeof(struct node*));

    // list 1 will contain
    one_a = (struct node*)malloc(sizeof(struct node));
    one_b = (struct node*)malloc(sizeof(struct node));

    // list 2 will contain
    two_a = (struct node*)malloc(sizeof(struct node));
    two_b = (struct node*)malloc(sizeof(struct node));
    // create linked list holding heads of 2 linked lists (i.e. first_list and second_list)

    // populate list1
    one_a->data = "a";
    one_a->next = one_b;
    one_b->data = "apple";
    one_b->next = NULL;

    // populate list2
    two_a>data = "be";
    two_a->next = two_b;
    two_b->data = "bite";
    two_b->next = NULL;

    // populate list of lists
    list_1->data = one_a->data;
    list_1->next = list_2;
    list_2->data = two_a->data;
    list_2->next = NULL;

}


6 commentaires

Laquelle est la tête de cette liste de listes?


list_1 n'est pas un pointeur vers struct mais un pointeur vers un pointeur, donc l'utilisation de -> n'est pas valide dans le dernier groupe d'affectations.


Pourquoi n'essayez-vous pas quelque chose comme struct node {char * data; struct node * next; struct node * innerListHead; }; ? Vous vous compliquez la vie avec ces doubles pointeurs.


@vasile_t mais c'est exactement ce qu'il a fait


@Jabberwocky comme je peux le comprendre, la liste intérieure n'est pas une liste mais un tableau? Comme ici / * allouer 6 nœuds dans le tas * / list_1 = (struct node **) malloc (sizeof (struct node *)); Mais il n'y a qu'un seul nœud, pas six. Est-ce que je me trompe?


@vasile_t oui plus ou moins. En fait, il veut une liste chaînée de listes mais il la mélange avec un pointeur vers un pointeur ...


3 Réponses :


3
votes

Vos list_1 et list_2 sont définis comme des pointeurs vers des pointeurs du nœud. Ce que vous voulez vraiment, c'est que list_1 et list_2 soient un nœud mais que leurs données soient des pointeurs vers d'autres nœuds. Étant donné que la structure de nœud que vous avez définie a les données définies comme un pointeur de caractère, votre nœud actuel ne fonctionnera pas pour list_1 et list_2. Vous pouvez modifier la structure pour utiliser un void-pointer ou vous pouvez créer une nouvelle structure pour contenir les nœuds. La solution la plus simple serait d'utiliser une nouvelle structure.

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

// node that can hold char * (strings) and next
struct node {
    char* data;
    struct node * next;
};

// node that can hold lists of nodes and next
struct lnode {
    struct node* data;
    struct lnode * next;
};


/*
I'm trying to create a linked list (containing List 1 and List 2) of linked lists, i.e.

    List 1         List 2
    1A               2A
    1B               2B

Where only nodes 1A, 1B, 2A and 2B have unique data (List 1 data just pointers to 1A data, List1 next just points to 1A next etc.)
*/





int main()
{

    // Will contain pointers to the heads of the 2 linked lists
    struct lnode* list_1 = NULL;
    struct lnode* list_2 = NULL;

    // Nodes under list_1
    struct node* one_a = NULL;
    struct node* one_b = NULL;

    // Nodes under linked list b
    struct node* two_a = NULL;
    struct node* two_b = NULL;

    // allocate 6 nodes in the heap
    list_1 = malloc(sizeof *list_1); //This style of malloc is better in the C language
    list_2 = malloc(sizeof *list_2);

    // list 1 will contain
    one_a = malloc(sizeof *one_a);
    one_b = malloc(sizeof *one_b);

    // list 2 will contain
    two_a = malloc(sizeof *two_a);
    two_b = malloc(sizeof *two_b);
    // create linked list holding heads of 2 linked lists (i.e. first_list and second_list)

    // populate list1
    one_a->data = "a";
    one_a->next = one_b;
    one_b->data = "apple";
    one_b->next = NULL;

    // populate list2
    two_a->data = "be";
    two_a->next = two_b;
    two_b->data = "bite";
    two_b->next = NULL;

    // populate list of lists
    list_1->data = one_a;//one_a is a pointer to the list
    list_1->next = list_2;
    list_2->data = two_a; //two_a is a pointer to the list
    list_2->next = NULL;

}


4 commentaires

Les moulages avant malloc ne sont pas nécessaires en C.


@Jabberwocky Bon point! Je les ai ajoutés car ils faisaient partie de son code d'origine. Je vais supprimer cela car ce n'est pas une bonne pratique.


Pour aller plus loin. La meilleure pratique pour C serait de list_1 = malloc (sizeof * list_1);


Merci Adam, le code était assez simple pour que je puisse le suivre. Très appréciée.



1
votes

Vous ne pouvez pas réaliser ce que vous essayez de faire uniquement avec cette structure. Vous avez besoin d'au moins deux pointeurs, l'un pour les éléments de la liste des listes et l'autre pour la liste des char * .

Le plus proche que vous pouvez obtenir ici avec le code que vous avez est d'un tableau de listes, en utilisant:

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


// node that can hold char * (strings) and next
struct node{
  char* data;
 struct  node* next;
};

struct list{
   struct list* next;
   struct node* curr_list;
};


int main(){


    struct node node2;
    node2.data="second";
    node2.next=NULL;


    struct node node1;
    node1.data="first";
    node1.next=&node2;

    struct list l1;
    l1.next=NULL;
    l1.curr_list= &node1;

    struct node node4;
    node4.data="fourth";
    node4.next=NULL;

    struct node node3;
     node3.data="third";
    node3.next= &node4;

    struct list l2;
    l2.next=NULL;
    l2.curr_list= &node3;

    l1.next = &l2;

    struct list* pl = &l1;
    int i = 0;
    while(pl){
         printf("%s %d\n","list",i++);

        struct node* n = pl->curr_list;
        while(n){
            printf("%s\n",n->data);

            n=n->next;
        }
        pl = pl->next;   
       printf("\n");
    }


 return 0;   
}

Pour réaliser ce que vous voulez, vous avez besoin d'une sorte de des structures comme les suivantes:

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

struct list{
   list* next;
   node* curr_list;
};

Comme vous pouvez le voir, vous avez maintenant un nœud spécial pour la liste de liste qui pointe à la fois vers l'élément suivant de la liste des listes et vers une liste normale de chaînes.

Voici l'exemple de code complet avec un main . Vous pouvez l'essayer ici .

list_1 = (struct node**)malloc(sizeof(struct node*) *  SIZE);


2 commentaires

Mauvais langage: la question est étiquetée C et votre code dans la réponse est C ++


Le cout n'est qu'un un problème



0
votes

En utilisant la réponse d'Adam, (et la logique de Davide concernant la fonction d'impression), je me suis retrouvé avec la démonstration suivante d'une liste simple et liée en C:

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

// node that can hold char * (strings) and next
struct node {
    char* data;
    struct node * next;
};

// node that can hold lists of lnodes and next
struct lnode {
    struct node* data;
    struct lnode * next;
};

/*
I'm trying to create a linked list (containing List 1 and List 2) of linked lists, i.e.

    List 1         List 2
    1A               2A
    1B               2B

Where only nodes 1A, 1B, 2A and 2B have unique data (List 1 data just pointers to 1A data, List1 next just points to 1A next etc.)
*/

int main()
{

    // Will contain pointers to the heads of the 2 linked lists
    struct lnode* list_1 = NULL;
    struct lnode* list_2 = NULL;

    // Nodes under list_1
    struct node* one_a = NULL;
    struct node* one_b = NULL;

    // Nodes under linked list b
    struct node* two_a = NULL;
    struct node* two_b = NULL;

    // allocate 6 nodes in the heap
    list_1 = malloc(sizeof *list_1); //This style of malloc is better in the C language
    list_2 = malloc(sizeof *list_2);

    // list 1 will contain
    one_a = malloc(sizeof *one_a);
    one_b = malloc(sizeof *one_b);

    // list 2 will contain
    two_a = malloc(sizeof *two_a);
    two_b = malloc(sizeof *two_b);

    // create linked list holding heads of 2 linked lists (i.e. first_list and second_list)
    // populate list1
    one_a->data = "a";
    one_a->next = one_b;
    one_b->data = "apple";
    one_b->next = NULL;

    // populate list2
    two_a->data = "be";
    two_a->next = two_b;
    two_b->data = "bite";
    two_b->next = NULL;

    // populate list of lists
    list_1->data = one_a;//one_a is a pointer to the list
    list_1->next = list_2;
    list_2->data = two_a; //two_a is a pointer to the list
    list_2->next = NULL;

    // to iterate over seperate lists (i.e. a's, b's, c's etc.)
    struct lnode *lists = list_1;
    while (lists){
        // to iterate through individual lists,(i.e. 'a', 'apple' etc.)
        struct node *head = lists->data;
        while (head) {
            printf("%s\n", head->data);
            head = head->next;
        }   
    lists = lists->next;
    } 

}


0 commentaires