Проблемы с простым указателем связанного списка (и ошибкой) - PullRequest
0 голосов
/ 14 марта 2019

Я нуб, борюсь с Си, указателями и связанными списками (ну все на самом деле). Я пытаюсь создать очень простой связанный список связанных списков, но я получаю сообщения об ошибках, в которых «базовый тип ссылки на элемент» struct node * 'не является структурой или объединением. Поработав некоторое время, меня осенило, что следующий по списку списков может одновременно указывать на следующий элемент списка в обоих местах, но я не уверен, требуется ли мне два типа узлов, или какой лучший способ сделать это.

#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;

}

Ответы [ 3 ]

3 голосов
/ 14 марта 2019

Ваши list_1 и list_2 определяются как указатели на указатели узла.То, что вы действительно хотите, чтобы list_1 и list_2 были узлами, а их данные - указателями на другие узлы.Поскольку в структуре узла, которую вы определили, данные определены как символьный указатель, ваш текущий узел не будет работать для list_1 и list_2.Вы можете изменить структуру для использования void-pointer или создать новую структуру для хранения узлов.Более простым решением будет использование новой структуры.

#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;

}
1 голос
/ 14 марта 2019

Вы не можете достичь того, что пытаетесь сделать только с этой структурой.Вам нужно как минимум два указателя, один для элементов списка списков, а другой для списка char*.

С кодом, который вы можете получить, вы можете получить массив массивов списков, используя:

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

.следующее:

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

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

Как видите, теперь у вас есть специальный узел для списка списка, который указывает как на следующий элемент списка списков, так и на список normal строк.

Ниже приведен полный пример кода с main.Вы можете попробовать это здесь .

#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;   
}
0 голосов
/ 17 марта 2019

Используя ответ Адама (и логику Давиде в отношении функции печати), я закончил следующей демонстрацией простого, односвязного списка в 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;
    } 

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...