Для начала в этом утверждении
temp = (list*)malloc(sizeof(list*));
^^^^^
выделена память размером, равным размеру указателя, а не размеру узла. Вы должны написать либо
temp = (list*)malloc(sizeof(list));
, либо
temp = (list*)malloc(sizeof( *temp));
Это выражение if
if (a->next == NULL)
может вызывать неопределенное поведение, поскольку изначально список может быть пустым. Таким образом, указатель a
может быть равен NULL. То есть для доступа к памяти используется пустой указатель.
Нет разницы между этими двумя блоками кода после частей if и else оператора if-else
if (a->next == NULL)//insert to the first node
{
temp->data = b;
temp->next = a;
a = temp;
}
else
{
temp->data = b;
temp->next = a;
a = temp;//
}
То есть фрагмент кода пытается вставить новый узел в начало списка.
Это общий подход для вставки нового узла в односвязный односторонний список в его начале. Добавить узел к такому списку до его конца неэффективно, потому что весь список должен быть пройден.
Если вы хотите добавить узел в конец односвязного списка, сделайте его двусторонним.
Вот демонстрационная программа.
#include <stdio.h>
#include <stdlib.h>
typedef struct Node
{
int data;
struct Node *next;
} Node;
typedef struct List
{
Node *head;
Node *tail;
} List;
int push_front( List *list, int data )
{
Node *new_node = malloc( sizeof( Node ) );
int success = new_node != NULL;
if ( success )
{
new_node->data = data;
new_node->next = list->head;
list->head = new_node;
if ( list->tail == NULL ) list->tail = list->head;
}
return success;
}
int push_back( List *list, int data )
{
Node *new_node = malloc( sizeof( Node ) );
int success = new_node != NULL;
if ( success )
{
new_node->data = data;
new_node->next = NULL;
if ( list->tail == NULL )
{
list->head = list->tail = new_node;
}
else
{
list->tail = list->tail->next = new_node;
}
}
return success;
}
void output( const List *list )
{
for ( const Node *current = list->head; current != NULL; current = current->next )
{
printf( "%d -> ", current->data );
}
puts( "null" );
}
int main(void)
{
List list = { .head = NULL, .tail = NULL };
const int N = 10;
for ( int i = 0; i < N; i++ )
{
if ( i % 2 != 0 )
{
push_front( &list, i );
}
else
{
push_back( &list, i );
}
output( &list );
}
return 0;
}
Его вывод
0 -> null
1 -> 0 -> null
1 -> 0 -> 2 -> null
3 -> 1 -> 0 -> 2 -> null
3 -> 1 -> 0 -> 2 -> 4 -> null
5 -> 3 -> 1 -> 0 -> 2 -> 4 -> null
5 -> 3 -> 1 -> 0 -> 2 -> 4 -> 6 -> null
7 -> 5 -> 3 -> 1 -> 0 -> 2 -> 4 -> 6 -> null
7 -> 5 -> 3 -> 1 -> 0 -> 2 -> 4 -> 6 -> 8 -> null
9 -> 7 -> 5 -> 3 -> 1 -> 0 -> 2 -> 4 -> 6 -> 8 -> null
В этой демонстрационной программе четные числа вставляются в конец списка с помощью функции push_back
и нечетные числа вставляются в начало списка с помощью функции push_front
.
Если ваш C компилятор не поддерживает назначенные инициализаторы, тогда это объявление
List list = { .head = NULL, .tail = NULL };
может изменить следующим образом
List list = { NULL, NULL };