Способ, которым вы печатаете список, должен работать нормально, если есть хотя бы один узел. Я бы порекомендовал изменить do { ... } while()
на while() { ... }
, чтобы он все еще работал, когда список пуст и head
равен NULL
:
trade_list *currentnode = head;
while (currentnode) {
printf ("Trade: %s Time: %d ID: %d\n",
currentnode->trader_msg,
currentnode->sender_timer,
currentnode->id_of_sender);
currentnode = currentnode->next;
}
Однако при добавлении в список возникают некоторые проблемы. Если head
не равно нулю, вы удаляете его ссылку на остальную часть списка:
if (head == NULL)
{
... /* skipped for brevity */
}
else
{
currentnode->next = NULL;
head = currentnode;
}
Поскольку в этот момент currentnode == head
, вы указываете head->next
на NULL (если бы был другой узел, вы бы выбросили его), а затем присваиваете head
себе.
Ваш код вставки в целом выглядит неправильно. Если вы хотите вставить только в начале списка, вам просто нужно что-то вроде:
trade_list *newnode = malloc(sizeof(trade_list));
/* *** Fill out newnode's fields here *** */
newnode->next = head;
head = newnode;
Если вы хотите вставить после произвольного узла, вы должны сначала найти его, пройдясь по списку, а затем сделать что-то вроде этого (держа более поздние времена во главе списка):
trade_list *newnode, *cur, *found;
/* Find the node with the smallest time >= curr_time_IN. 'found' starts as NULL, then
is always the node before 'cur'. 'cur' moves through the list until its time is
less than 'curr_time_IN'. So at the end, 'cur' is the first node that's too far in,
and 'found' is either NULL or the node we insert after. */
found = NULL;
for (cur = head; cur && cur->sender_timer >= curr_time_IN; cur = cur->next)
found = cur;
if (found) {
/* If 'found' isn't NULL, we're inserting after it (or skipping if the times match,
since that seems to be what the original code was trying to do) */
if (found->sender_timer == curr_time_IN) {
/* Times match: skip it */
printf("SKIPPED\n");
} else {
/* inserting after 'found' */
newnode = malloc(sizeof(*newnode));
/* *** Fill out newnode's fields here *** */
newnode->next = found->next;
found->next = newnode;
}
} else {
/* No node with more recent time found -- inserting at 'head' */
newnode = malloc(sizeof(*newnode));
/* *** Fill out newnode's fields here *** */
newnode->next = head;
head = newnode;
}
Отредактировано после комментария:
Чтобы изменить список для сортировки по убыванию по времени, а затем по ID в порядке возрастания, требуется всего пара изменений.
Редактировать
Поскольку исходный цикл for
для поиска узла продолжается до последнего узла, который соответствует критериям, нам просто нужно добавить тест в цикл, чтобы разорвать его, когда мы окажемся на правильном ... то есть разрывать, если следующий узел имеет равное время и более высокий ID, поскольку в этом случае мы хотим вставить перед этим. (предыдущая редакция была ошибочной ... извините за это).
Кроме того, проверка if (found->sender_timer == curr_time_IN)
впоследствии больше не требуется, поскольку пропуски не выполняются, а сортировка по идентификатору обрабатывается новым циклом for
.
Итак, этот фрагмент кода становится:
/* original search */
for (cur = head; cur && cur->sender_timer >= curr_time_IN; cur = cur->next) {
/* *** added condition for ID sort */
if (cur->sender_timer == curr_time_IN && cur->id_of_sender >= my_id_IN) break;
found = cur;
}
if (found) {
/* If 'found' isn't NULL, we're inserting after it */
/* CHANGED: no need to skip when times are equal */
newnode = malloc(sizeof(*newnode));
/* *** Fill out newnode's fields here *** */
newnode->next = found->next;
found->next = newnode;
} else {
/* No node with more recent time found -- inserting at 'head' */
newnode = malloc(sizeof(*newnode));
/* *** Fill out newnode's fields here *** */
newnode->next = head;
head = newnode;
}