Создание связанного списка в C с использованием цикла for для присвоения значений - PullRequest
0 голосов
/ 22 октября 2019

Я пытаюсь создать связанный список для моей программы, используя цикл for, который присваивает значения. При создании этого связанного списка я хочу иметь возможность отслеживать заголовок и иметь первое значение в цикле for, назначенное заголовку. Например, если я создаю список от 0 до n - 1, я хочу, чтобы заголовок указывал на 0, а за остальной частью списка следовали 1-2-3-4 -...- n-1. Я запрограммировал цикл, который делает именно это, однако цикл for должен вести обратный отсчет, а не вперед. Вот мой код:

// Structure
typedef struct node {
  int value;
  struct node * next;
} ListNode;

  int size = "some value"; 

  ListNode * head = NULL; // beginning of the linked list
  ListNode * temp; // temporary node  

  for(int count = size - 1; count >= 0; count--)
  {
    // creates temporary nodes //
    ListNode * tempNode = malloc(sizeof(ListNode));
    tempNode -> value = count;
    tempNode -> next = NULL;
    // creation of node completed

    temp = tempNode;
    temp -> next = head;
    head = temp;
  }

Хотя в этой программе голова указывает на 0, как я намереваюсь, есть ли способ, чтобы цикл for начинался с 0 вплоть до n и по-прежнему производил то же самое? выход. Я хотел бы, чтобы это выглядело (int для count = 0; count

1 Ответ

0 голосов
/ 22 октября 2019

Во-первых, в вашем коде вам не нужны дополнительные tempNode, просто используйте temp и сделайте его локальным для внутреннего блока:

for (int count = size; count--; ) {
    ListNode *temp = malloc(sizeof(*temp));

    temp->value = count;
    temp->next = head;
    head = temp;
}

Если вы хотите добавить элементы вв конце вы должны сохранить указатель на последний узел, tail:

ListNode *head = NULL;
ListNode *tail = NULL;

for (int count = 0; count < size; count++) {
    ListNode *temp = malloc(sizeof(*temp));

    temp->value = count;
    temp->next = NULL;

    if (tail == NULL) {
        head = temp;
        tail = temp;
    } else {
        tail->next = temp;
        tail = temp;
    }
}

Существует более элегантный способ сделать это: вместо того, чтобы хранить указатель на последний узел, сохраняйте указательна нулевой указатель, куда должен идти следующий элемент:

ListNode *head = NULL;
ListNode **tail = &head;

for (int count = 0; count < size; count++) {
    ListNode *temp = malloc(sizeof(*temp));

    temp->value = count;
    temp->next = NULL;

    *tail = temp;
    tail = &(*tail)->next;
}

В начале *tail содержит адрес head, после этого он будет содержать адрес члена nextпоследний узелВы можете обновить оба с помощью указателя tail без необходимости проверки, является ли список пустым.

Этот последний метод поначалу выглядит немного устрашающе с его ListNode **tail, но как только вы получите зависаниеэто полезный инструмент, чтобы иметь. Если вам это пока не нравится, используйте первый вариант.

Стоит ли усилий только для составления списка вперед? Вставка в список спереди очень проста, и после очистки ваш оригинальный вариант выглядит чистым и компактным для меня.

...