Динамический список - C (СИ)

Узнай цену своей работы

Формулировка задачи:

Здравствуйте! Есть код (задание в заголовке)
#include <stdio.h>
#include <stdlib.h>
 
#define DB printf("%d\n", __LINE__);
 
typedef struct Node
{
    int value;
    struct Node *next;
} node;
 
typedef struct List
{
    node *first;
    node *last;
} list;
 
void init_list(list *l) // очищает список
{
    l->first = NULL;
    l->last  = NULL;
}
 
void push_back(list *l, int val) // вставляет элемент в конец
{
    node new = {val, NULL};
 
    if(l->first == NULL) // если список пустой
    {
        l->first = &new;
        l->last = &new;
        return;
    }
 
    l->last->next = &new;
    l->last = &new;
}
 
int list_size(list l)
{
    node *buff = l.first;
    int size = 1;
 
    while(buff != l.last)
    {
        buff = buff->next;
        size++;
    }
 
    return size;
}
 
void print_all(list l)
{
    node *buff = l.first;
    printf("start = %d end = %d \n", l.first, l.last);
 
    while(buff != l.last)
    {
        printf("'%d' ", buff->value);
        buff = buff->next;
    }
 
    printf("\n");
}
 
int main()
{
    list a;
 
    init_list(&a);
    push_back(&a, 2);
    push_back(&a, 3);
    push_back(&a, 4);
    push_back(&a, 5);
    
    printf("%d\n", list_size(a));
 
    print_all(a);
    
    return 0;
}
Путем нехитрых экспериментов, было установлено, что

a.first

всегда равен

a.last

, при том, что в ф-ции

push_back

, вроде сказано, что равны они только в двух случаях - когда список пустой или когда там только один элемент. Из всего выше сказанного следует, что длинна всегда равна

1

, а

print_all

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

Решение задачи: «Динамический список»

textual
Листинг программы
#include <stdio.h>
#include <stdlib.h>
 
#define DB printf("%d\n", __LINE__);
 
typedef struct Node {
    int value;
    struct Node* next;
} node;
 
typedef struct List {
    node* first;
    node* last;
} list;
 
 
void push_back(list* l, int val) { // вставляет элемент в конец
    node* new = malloc(sizeof(node));
    new->value = val;
    new->next = NULL;
 
    if (l->first == NULL) { // если список пустой
        l->first = l->last = new;
    }
    else {
        l->last->next = new;
        l->last = new;
    }
}
 
int list_size(const list l) {
    const node* buff = l.first;
    int size = 0;
 
    for (; buff; buff = buff->next, ++size) { ; }
 
    return size;
}
 
void print_all(const list l) {
    const node* buff = l.first;
 
    for (; buff; buff = buff->next) {
        printf("'%d' ", buff->value);
    }
    printf("\n");
}
 
int main() {
    list a = {NULL, NULL};
 
    push_back(&a, 2);
    push_back(&a, 3);
    push_back(&a, 4);
    push_back(&a, 5);
 
    printf("%d\n", list_size(a));
 
    print_all(a);
 
    return 0;
}

Объяснение кода листинга программы

  1. Включаются заголовочные файлы stdio.h и stdlib.h
  2. Определяется макрос DB, который выводит номер строки, где происходит ошибка
  3. Определяются структуры Node и List
  4. В функции push_back создается новый узел, и его значение присваивается переданному значению
  5. Если список пустой, то новый узел становится первым и последним
  6. В противном случае новый узел вставляется в конец списка
  7. В функции list_size перебираются все узлы списка, пока не будет NULL, и подсчитывается количество узлов
  8. В функции print_all перебираются все узлы списка, и выводится значение каждого узла
  9. В основной функции создается пустой список
  10. В список добавляются четыре элемента
  11. Выводится размер списка
  12. Выводится содержимое списка
  13. Программа возвращает 0, заканчивая свое выполнение

Оцени полезность:

10   голосов , оценка 3.9 из 5
Похожие ответы