Вопрос

Я пытаюсь сделать связанный список похожим на тот, что здесь:

связанный список в C

То есть иметь «голову», как я ее назвал первым, внутри другой структуры.Однако я обнаружил, что делаю это изменение.Усложняет добавление значений в структуру list_item.Я попробовал несколько вещей, чтобы проверить, работает ли это.Он компилируется, однако, когда я запускаю код, происходит сбой.Любая помощь здесь будет полезна.Я знаю, что причина сбоя в том, что я хочу указать new_node на linked_list.

#include <iostream>

using namespace std;

struct list_item
{
    int key;
    int value;
    list_item *next;
};

struct list
{
    struct list_item *first;
};

int main()
{
    list *head;
    list *new_node;

    head = NULL;
    head->first = NULL;

    for(int i = 0; i < 10; i++)
    {
        //allocate memory for new_node
        new_node = (list*)malloc(sizeof(list));
        new_node->first = (list_item*)malloc(sizeof(list_item));
        //adding the values
        new_node->first->key = i;
        new_node->first->value = 10 + i;

        //point new_node to first;
        new_node->first->next = head->first;

        //point first to new_node;
        head->first = new_node->first;

    }

    //print
     list *travel;
     travel->first = head->first;

     int i = 0;
     while(travel != NULL)
     {
         cout << travel->first->value << endl;
         travel->first = travel->first->next;
     }

    return 0;
}
Это было полезно?

Решение

Вы создаете 10 списков, я думаю, вы можете попробовать сделать что-то вроде этого:

#include <iostream>

using namespace std;

struct list_item
{
    int key;
    int value;
    list_item *next;
};

struct list
{
    struct list_item *first;
};

int main()
{
    //Just one head is needed, you can also create this
    // on the stack just write:
    //list head;
    //head.first = NULL;
    list *head = (list*)malloc(sizeof(list));
    list_item *new_node = NULL;

    head->first = NULL;

    for(int i = 0; i < 10; i++)
    {
        //allocate memory for new_node
        new_node = (list_item*)malloc(sizeof(list_item));
        //adding the values
        new_node->key = i;
        new_node->value = 10 + i;

        //if the list is empty, the element you are inserting
        //doesn't have a next element

        new_node->next = head->first;

        //point first to new_node. This will result in a LIFO
        //(Last in First out) behaviour. You can see that when you 
        //compile
        head->first = new_node;

    }

     //print the list 
     list_item *travel;
     travel = head->first;

     while(travel != NULL)
     {
         cout << travel->value << endl;
         travel = travel->next;
     }

    //here it doesn't matter, but in general you should also make
    //sure to free the elements
    return 0;
}

Вот что происходит.Сначала у вас есть только одна голова и никаких элементов.

head
  |
  |
  V
 NULL

Затем вы добавляете свой первый элемент.Убедитесь, что «new_node->next==NULL»:

head
  |
  |
  V
node:   ------------------> NULL
key = 0
value = 10

Затем вы добавляете еще один узел впереди, но добавляете свой первый узел к следующему узлу.вы перемещаете указатель с головы на новый узел

head:
first
  |
  |
  V
node:   ---------> node:  -------------> NULL
key: 1             key: 0   
value: 11          value: 10  

и т. д.

Поскольку вы используете C++, вы можете рассмотреть возможность использования «нового» и «удалить».Просто замените

new_node = (list_item*)malloc(sizeof(list_item));

с

list *head = new list

Другие советы

Я думаю, вы хотите что-то более похожее на это:

#include <iostream>
#include <cstdlib>

using namespace std;

typedef struct tag_list_item
{
    int key;
    int value;
    struct tag_list_item *next;
} list_item;

typedef struct
{
    list_item *head;
} list;

int main()
{
    list my_list;
    list_item *new_node;
    list_item *previous_node = NULL;

    my_list.head = NULL;

    for(int i = 0; i < 10; i++)
    {
        //allocate memory for new_node
        new_node = (list_item*)malloc(sizeof(list_item));

        //adding the values
        new_node->key = i;
        new_node->value = 10 + i;

        if(previous_node == NULL)
        {
            my_list.head = new_node;
        }
        else
        {
            previous_node->next = new_node;
        }
        previous_node = new_node;    
    }

    //print
     list_item *iter = my_list.head;

     while(iter != NULL)
     {
         cout << iter->value << endl;
         iter = iter->next;
     }

    return 0;
}

Изменения заметки:

Для malloc я добавил:

#include <cstdlib>

Я изменил ваши структуры списков на typedefs, должен был объявить " next " использование тега, так как typedef на этом этапе не завершен

typedef struct tag_list_item
{
    int key;
    int value;
    struct tag_list_item *next;
} list_item;

Я изменил название вашего списка на "my_list" и объявил это напрямую (без указателя). В этом случае вы можете просто назначить компилятору его автоматически в стеке.

list my_list;

Я сохраняю указатель на " предыдущий_узел " так что вы можете назначить " далее " указатель гораздо проще. Обратите внимание, что на первый выделенный узел указывает " head " указатель в структуре списка. Я считаю, что это традиционное имя для указателя на первый элемент в списке.

if(previous_node == NULL)
{
    my_list.head = new_node;
}
else
{
    previous_node->next = new_node;
}
previous_node = new_node;

Следующая строка выделяет память только для вашей структуры list . Список содержит только указатель, вы также должны выделить память для new_node-> gt; first перед назначением любому из его членов.

//allocate memory for new_node
new_node = (list*)malloc(sizeof(list));
head = NULL;
head->first = NULL;

Есть проблема. Вы не можете следовать за указателем и установить его в NULL, если сам указатель установлен в NULL.

Это должно быть

head = malloc(sizeof(list));
head->first = NULL;

Это должно исправить ваш код.

Надеюсь, это поможет, Billy3

РЕДАКТИРОВАТЬ: есть также проблема с вашим циклом FOR. Когда вы распределяете список, вы должны распределять сам список только один раз. Когда вы вставляете элемент, вы выделяете только list_item. Вы назначаете указатель списка члену, который принимает только указатель list_item;)

См. сообщение Гейба для демонстрации правильного поведения:)

Посмотрите на объявление структуры

struct list_item
{
    int key;
    int value;
    list_item *next;
};

Это должно быть

struct list_item
{
    int key;
    int value;
    struct list_item *next;
};

Надеюсь, это поможет, С наилучшими пожеланиями, Том

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top