how to make a struct with void * data? - c

i have this struct :
struct node
{
int data;
struct node *next;
};
so the following strcut has an int data , i want the function to accept CopyFunction which is baisicly a pointer to a function that accepts void* and returns void* , i want my function to get a copy of the data in the first node connected to a copy f the second data , now i want the data to be not only int i want to use this function on any data so i used CopyFunction to be pointer to a function that as i saied accepts void* ... how can i use this in the function bellow .. for example if i want to change the struct to be :
struct node
{
Element data;
struct node *next;
};
typedef void* Element;
typedef Element (*copy_function) (Element);
struct node * concatLists( struct node *head1, struct node *head2, int cmp( struct node *),copy_function CopyFunction)
{
struct node *head = NULL;
struct node **current = &head;
for ( ; head1 != NULL; head1 = head1->next )
{
if ( cmp( head1 ) )
{
*current = malloc( sizeof( struct node ) );
( *current )->data = CopyFunction(head1->data);
( *current )->next = NULL;
current = &( *current )->next;
}
}
for ( ; head2 != NULL; head2 = head2->next )
{
if ( cmp( head2 ) )
{
*current = malloc( sizeof( struct node ) );
( *current )->data = CopyFunction(head2->data);
( *current )->next = NULL;
current = &( *current )->next;
}
}
and then if i have a int struct i can just use this function with a copy function for int like this :
static void* copyInt(void* num){
int* newInt=malloc(sizeof(*newInt));
*newInt=*(int*)num;
return newInt;
}
also i think it is better if i change and without using always struct node * i want to have maybe: typedef struct node_t* Node;

concatLists(..., (copy_function)copyInt)
Providing all the "methods" (cmp and CopyFunction) as parameters gets silly fast. Why not create a List "object" that holds not just a pointer to the head and tail, but the "methods" to genericize the list too.
cmp is probably a compare function (which means it should take two arguments), which means you are probably trying to merge sorted lists. Well, here's code that uses a generic list implementation to do just that. (I figured I might as well make malloc and free plugable as well.)
#include <stdio.h>
#include <stdlib.h>
// -----
// ListNode type declarations.
typedef struct ListNode {
void* data;
struct ListNode* prev;
struct ListNode* next;
} ListNode;
// -----
// ListType type declarations.
typedef void* (* Allocator )(size_t);
typedef void (* Deallocator )(void*);
typedef void (* FreeFunction )(void*);
typedef int (* CmpFunction )(void*, void*);
typedef void* (* CopyFunction )(void*);
typedef struct {
Allocator malloc;
Deallocator free;
FreeFunction free_data;
CmpFunction cmp;
CopyFunction copy;
} ListType;
// -----
// List type declarations.
typedef struct {
const ListType* list_type;
ListNode* head;
ListNode* tail;
} List;
typedef void (*ListVisitor)(void*);
// -----
// ListDataInt definitions.
static void* ListDataInt_new(int i) {
int* ip = malloc(sizeof(int));
*ip = i;
return ip;
}
static void ListDataInt_free_data(int* ip) {
free(ip);
}
static int ListDataInt_cmp(const int* ap, const int* bp) {
if (*ap < *bp) return -1;
if (*ap > *bp) return +1;
return 0;
}
static int* ListDataInt_copy(const int* orig_ptr) {
int* new_ptr = malloc(sizeof(int));
*new_ptr = *orig_ptr;
return new_ptr;
}
static const ListType ListDataInt_list_type = {
malloc,
free,
(FreeFunction)ListDataInt_free_data,
(CmpFunction)ListDataInt_cmp,
(CopyFunction)ListDataInt_copy
};
// -----
// ListNode definitions.
static ListNode* ListNode_new(List* list, void* data) {
const ListType* list_type = list->list_type;
ListNode* node = list_type->malloc(sizeof(ListNode));
node->data = data;
node->prev = NULL;
node->next = NULL;
return node;
}
static void ListNode_free(List* list, ListNode* node) {
const ListType* list_type = list->list_type;
list_type->free_data(node->data);
list_type->free(node);
}
// -----
// List definitions.
static List* List_new(const ListType* list_type) {
List* list = list_type->malloc(sizeof(List));
list->list_type = list_type;
list->head = NULL;
list->tail = NULL;
return list;
}
static void List_free(List* list) {
ListNode* next = list->head;
while (next != NULL) {
ListNode* node = next;
next = node->next;
ListNode_free(list, node);
}
list->list_type->free(list);
}
static void List_push(List* list, ListNode* node) {
if (list->tail == NULL) {
list->head = list->tail = node;
} else {
list->tail->next = node;
node->prev = list->tail;
list->tail = node;
}
}
static void List_push_data(List* list, void* data) {
List_push(list, ListNode_new(list, data));
}
static void List_visit(List* list, ListVisitor visitor) {
for (ListNode* node = list->head; node != NULL; node = node->next) {
visitor(node->data);
}
}
// -----
// Main program.
static List* merge_sorted_lists(List* list1, List* list2) {
const ListType* list_type = list1->list_type;
List* new_list = List_new(list_type);
ListNode* src1 = list1->head;
ListNode* src2 = list2->head;
while (src1 != NULL && src2 != NULL) {
int cmp = list_type->cmp(src1->data, src2->data);
if (cmp <= 0) {
List_push(new_list, ListNode_new(new_list, list_type->copy(src1->data)));
src1 = src1->next;
}
if (cmp >= 0) {
List_push(new_list, ListNode_new(new_list, list_type->copy(src2->data)));
src2 = src2->next;
}
}
while (src1 != NULL) {
List_push(new_list, ListNode_new(new_list, list_type->copy(src1->data)));
src1 = src1->next;
}
while (src2 != NULL) {
List_push(new_list, ListNode_new(new_list, list_type->copy(src2->data)));
src2 = src2->next;
}
return new_list;
}
static void dumper(const int* ip) {
printf("%d\n", *ip);
}
int main(void) {
List* sorted_int_list1 = List_new(&ListDataInt_list_type);
List_push_data(sorted_int_list1, ListDataInt_new(4));
List_push_data(sorted_int_list1, ListDataInt_new(6));
List_push_data(sorted_int_list1, ListDataInt_new(8));
List* sorted_int_list2 = List_new(&ListDataInt_list_type);
List_push_data(sorted_int_list2, ListDataInt_new(5));
List_push_data(sorted_int_list2, ListDataInt_new(7));
List_push_data(sorted_int_list2, ListDataInt_new(9));
List* merged_sorted_int_list =
merge_sorted_lists(sorted_int_list1, sorted_int_list2);
List_visit(merged_sorted_int_list, (ListVisitor)dumper);
List_free(sorted_int_list1);
List_free(sorted_int_list2);
List_free(merged_sorted_int_list);
return 0;
}
Test:
$ gcc -Wall -Wextra -pedantic --std=c99 -o a a.c && a
4
5
6
7
8
9

Related

Generic LinkedLists in C

I am quite new to C and having a lot of trouble with generic linked lists in c.
Im trying to convert my linked list into a generic one but I don't really understand how to.
This is my original one:
typedef struct LLNode {
int rowPos;
int colPos
char Charecter
struct LLNode *next;
} LLNode;
typedef struct LinkedList {
LLNode *head;
LLNode *tail;
int ROW;
int COL;
int appleCount;
int winCon;
int snakeSize;
} LinkedList;
I understand that the data has to be a void but can you have more than one void *data; in a node.
So far I have this:
typedef struct LLNode {
void *data;
struct LLNode *next;
} LLNode;
typedef struct LinkedList {
LLNode *head;
LLNode *tail;
int ROW;
int COL;
int appleCount;
int winCon;
int snakeSize;
} LinkedList;
But I don't know how I go about accessing and changing 3 lots of data in one void *data.
You can use macros:
#define LNODE(Type) LNode_ ## Type
#define LLIST(Type) LList_ ## Type
#define DECL_LINKED_LIST(Type) \
typedef struct LNODE(Type) { Type value; struct LNODE(Type)* next; } LNODE(Type); \
typedef struct LLIST(Type) { LNODE(Type)* head; LNODE(Type)* tail; } LLIST(Type);
typedef struct {
char const* f_name;
char const* l_name;
} Person;
DECL_LINKED_LIST(Person);
int main() {
LLIST(Person) list;
LNODE(Person) node1;
list.head = list.tail = &node1;
node1.next = 0;
node1.value.f_name = "John";
node1.value.l_name = "Smith";
}
It's somewhat ugly, but it works. Alternatively, if you can use a C++ compiler instead, you can use templates.
C does not have typed generic aggregates such as C++ templates, but you can implement simpler aggregates pointing to data items via void * pointers. You can also use macros to mix the data and the aggregation internals, but it requires more advanced C skills.
Here is an example using void * for data:
#include <stdio.h>
#include <stdlib.h>
/* generic list handling */
typedef struct LLNode {
struct LLNode *next;
void *data;
} LLNode;
typedef struct LinkedList {
LLNode *head;
LLNode *tail;
} LinkedList[1];
void LinkedList_init(LinkedList list) {
if (list) {
list->head = list->tail = NULL;
}
}
void *LinkedList_append(LinkedList list, void *data) {
if (list) {
LLNode *node = malloc(sizeof(*node));
if (node != NULL) {
node->data = data;
node->next = NULL;
if (list->head == NULL) {
list->head = list->tail = node;
} else {
list->tail = list->tail->next = node;
}
return data;
}
}
return NULL;
}
void *LinkedList_delete(LinkedList list, void *data) {
if (list) {
for (LLNode **np = &list->head, *last = NULL; *np;) {
LLNode *node = *np;
if (node->data == data) {
if ((*np = node->next) == NULL)
list->tail = last;
free(node);
return data;
} else {
last = node;
np = &node->next;
}
}
}
return NULL;
}
void LinkedList_free(LinkedList list, int free_data) {
if (list) {
for (LLNode *node = list->head, *next; node; node = next) {
next = node->next;
if (free_data)
free(node->data);
free(node);
}
list->head = list->tail = NULL;
}
}
#define LinkedList_foreach(var, list) \
for (LLNode *np__ = (list)->head, *next__; np__ != NULL; np__ = next__) \
for (var = (next__ = np__->next, np__)->data; np__; np__ = NULL)
/* use a generic list for my data */
typedef struct MyData {
int rowPos;
int colPos;
char Character;
} MyData;
typedef struct MyList {
int ROW;
int COL;
int appleCount;
int winCon;
int snakeSize;
LinkedList list; // linked list of MyData items
} MyList;
MyList *MyList_alloc(void) {
MyList *lp = calloc(sizeof(*lp), 1);
LinkedList_init(lp->list);
return lp;
}
void MyList_free(MyList *lp) {
LinkedList_free(lp->list, 1);
free(lp);
}
MyData *MyList_add(MyList *lp, int row, int col, char c) {
MyData *dp = malloc(sizeof(*dp));
dp->rowPos = row;
dp->colPos = col;
dp->Character = c;
return LinkedList_append(lp->list, dp);
}
void MyList_delete(MyList *lp, MyData *dp) {
free(LinkedList_delete(lp->list, dp));
}
void MyList_print(MyList *lp) {
printf("{\n");
LinkedList_foreach(MyData *dp, lp->list) {
printf(" { %d, %d, '%c' }\n", dp->rowPos, dp->colPos, dp->Character);
}
printf("};\n");
}
void MyList_filter_diagonal(MyList *lp) {
LinkedList_foreach(MyData *dp, lp->list) {
if (dp->rowPos == dp->colPos)
MyList_delete(lp, dp);
}
}
int main() {
MyList *mylist = MyList_alloc();
MyList_add(mylist, 0, 0, 'A');
MyData *d1 = MyList_add(mylist, 1, 2, 'B');
MyList_add(mylist, 2, 2, 'C');
MyList_add(mylist, 3, 5, 'D');
MyList_print(mylist);
MyList_delete(mylist, d1);
MyList_print(mylist);
MyList_filter_diagonal(mylist);
MyList_print(mylist);
MyList_free(mylist);
return 0;
}

linked list implemetation from scratch, segmentation fault

I want to implement linked list from scratch. I programmed it, but when I run it gives me a Segmentation fault in my node_adder(int data) function. I don't know what caused this.
struct linked_list
{
int value;
struct linked_list *next;
};
struct linked_list *head = NULL;
struct linked_list *tail = NULL;
void node_adder(int data)
{
struct linked_list *new = NULL;
new->value = data;
new->next = NULL;
if (head == NULL)
{
head = new;
tail = new;
printf("head added\n");
}
else
{
tail->next = new;
tail = new;
printf("tail added\n");
}
}
In node_adder(), you are not allocating any memory for the new node before accessing its members.
Try this instead:
struct linked_list
{
int value;
struct linked_list *next;
};
struct linked_list *head = NULL;
struct linked_list *tail = NULL;
void node_adder(int data)
{
struct linked_list *newNode;
// ADD THIS!!!
// in C:
newNode = malloc(sizeof(struct linked_list));
// in C++:
newNode = new linked_list;
//
newNode->value = data;
newNode->next = NULL;
if (head == NULL)
{
head = tail = newNode;
printf("head added\n");
}
else
{
tail->next = newNode;
tail = newNode;
printf("tail added\n");
}
}
This line initializes a pointer to a node to NULL:
struct linked_list *new = NULL;
Yet, no memory is allocated for this node. Therefore, in this line, attempting to assign a value to one of the members of the node leads to a segmentation fault:
new->value = data;
You probably meant to do this:
struct linked_list *new = malloc(sizeof(struct linked_list));
Of course, a corresponding free(..) should also be added when the allocated memory will no longer be used.
For starters it is a bad idea to declare global variables and define functions that depend on the global variables as you are doing
struct linked_list *head = NULL;
struct linked_list *tail = NULL;
because in this case you will not be able to define for example more than one list.
It is much better to introduce one more structure like for example
struct node
{
int value;
struct node *next;
};
struct linked_list
{
struct node *head;
struct node *tail;
};
As for your problem then you are using a null pointer to access memory that results in undefined behavior
void node_adder(int data)
{
struct linked_list *new = NULL;
new->value = data;
new->next = NULL;
//...
You need to allocate a node dynamically as for example
int node_adder(int data)
{
struct linked_list *new = malloc( sizeof( *new ) );
int success = new != NULL;
if ( success )
{
new->value = data;
new->next = NULL;
if (head == NULL)
{
head = new;
}
else
{
tail->next = new;
}
tail = new;
}
return success;
}
But using the approach I showed in the beginning of my answer You could write instead
struct node
{
int value;
struct node *next;
};
struct linked_list
{
struct node *head;
struct node *tail;
};
int node_adder( struct linked_list *list, int data )
{
struct node *new = malloc( sizeof( *new ) );
int success = new != NULL;
if ( success )
{
new->value = data;
new->next = NULL;
if (list->head == NULL)
{
list->head = new;
}
else
{
list->tail->next = new;
}
list->tail = new;
}
return success;
}
and in main you can write
int main( void )
{
struct linked_list list = { .head = NULL, .tail = NULL };
node_adder( &list, 10 );
//...
}

Sorting a singly linked list with multiple elements in C [duplicate]

In C I have to write a bubble sort function that swaps the nodes and not the values of a LinkedList, but I'm unable to accomplish it. Here is the code (As you can see the order is not correct):
#include <stdio.h>
#include <malloc.h> // malloc, free
#include <stddef.h> // NULL
// defining 'int' as data_t
typedef int data_t;
typedef struct node_s {
data_t data;
struct node_s* next;
} node_t;
node_t** list_new() {
node_t** list = malloc(sizeof **list);
if (!list) return NULL;
*list = NULL;
return list;
}
void list_delete(node_t** list) {
node_t *node, *next;
for (node = *list; node; node = next) {
next = node->next;
free(node);
}
}
node_t* list_push_front(node_t** list, data_t data) {
node_t* node = malloc(sizeof(node_t));
if (!node) return NULL;
node->data = data;
node->next = *list;
return *list = node;
}
// IS EASY TO SWAP THE VALUES
/*
void swap(data_t* a, data_t* b) {
data_t c = *a;
*a = *b;
*b = c;
}
void simple_bubble_sort(node_t** list) {
for(node_t* i = *list; i; i = i->next)
for(node_t* j = *list; j->next; j = j->next)
if(j->data > j->next->data)
swap(&(j->data), &(j->next->data));
}
*/
// MUCH LESS EASY TO SWAP THE NODES
void swap_node(node_t** prev_node_A, node_t** node_A, node_t** node_B) {
node_t *last_node = (*node_B)->next;
node_t *first_node = *node_A;
node_t *second_node = *node_B;
if (prev_node_A) {
(*prev_node_A)->next = second_node;
(*prev_node_A)->next->next = first_node;
(*prev_node_A)->next->next->next = last_node;
} else {
(*node_A) = second_node;
(*node_A)->next = first_node;
(*node_A)->next->next = last_node;
}
}
void simple_bubble_sort(node_t** list) {
for(node_t* i = *list; i->next; i = i->next)
for (node_t *j = *list; j->next->next; j = j->next) {
if (j == *list) {
if (j->data > j->next->data) {
*list = j->next;
swap_node(NULL, &j, &(j->next));
}
}
else {
if (j->next->data > j->next->next->data)
swap_node(&j, &(j->next), &(j->next->next));
}
//printf("%i,%i | %i, %i, %i, %i \n", i->data, j->data, (*list)->data, (*list)->next->data, (*list)->next->next->data, (*list)->next->next->next->data);
//system("pause");
}
}
int main() {
// Create List
node_t** list = list_new();
if (!list)
goto memory_allocation_failure;
// Add values to List
for(int i=0; i<10; i++)
if (!list_push_front(list, i))
goto memory_allocation_failure;
// Print List
for (node_t* node = *list; node != NULL; node = node->next)
printf("%i\n", node->data);
// Swap Test
//swap_node(NULL, &(*list), &((*list)->next));
//swap_node(&(*list), &((*list)->next), &((*list)->next->next));
// Sort List
printf("-- Bubble Sort --\n");
simple_bubble_sort(list);
// Print List
for (node_t* node = *list; node != NULL; node = node->next)
printf("%i\n", node->data);
// Delete List
list_delete(list);
return 0;
// Error Handler
memory_allocation_failure:
printf("Memory Allocation Failure");
return 1;
}
Here is the function swap.
void swap( node_t **current )
{
node_t *tmp = ( *current )->next->next;
( *current )->next->next = *current;
*current = ( *current )->next;
( *current )->next->next = tmp;
}
And here is the function simple_bubble_sort
void simple_bubble_sort( node_t **head )
{
if ( *head )
{
for ( node_t **first = head, *sorted = NULL, *last = sorted;
( *first )->next != last;
last = sorted )
{
sorted = ( *first )->next;
for ( node_t **current = first; ( *current )->next != last; current = &( *current )->next )
{
if ( ( *current )->next->data < ( *current )->data )
{
swap( current );
sorted = ( *current )->next;
}
}
}
}
}
Investigate them.
Pay attention to that the header <malloc.h> is not a standard C header. Instead use the header <stdlib.h>.
You need to revise your current code. For example this function
node_t** list_new() {
node_t** list = malloc(sizeof **list);
if (!list) return NULL;
*list = NULL;
return list;
}
does not make sense it should be removed.
What you need is just to define in main a pointer like
node_t *head = NULL;
And pass it to functions as for example to the function simple_bubble_sort like
simple_bubble_sort( &head );
Or the function list_push_front should be defined like
int list_push_front(node_t** list, data_t data)
{
node_t* node = malloc(sizeof(node_t));
int success = node != NULL;
if ( success )
{
node->data = data;
node->next = *list;
*list = node;
}
return success;;
}

How do I swap the nodes of a linked list in a bubble-sort algorithm?

In C I have to write a bubble sort function that swaps the nodes and not the values of a LinkedList, but I'm unable to accomplish it. Here is the code (As you can see the order is not correct):
#include <stdio.h>
#include <malloc.h> // malloc, free
#include <stddef.h> // NULL
// defining 'int' as data_t
typedef int data_t;
typedef struct node_s {
data_t data;
struct node_s* next;
} node_t;
node_t** list_new() {
node_t** list = malloc(sizeof **list);
if (!list) return NULL;
*list = NULL;
return list;
}
void list_delete(node_t** list) {
node_t *node, *next;
for (node = *list; node; node = next) {
next = node->next;
free(node);
}
}
node_t* list_push_front(node_t** list, data_t data) {
node_t* node = malloc(sizeof(node_t));
if (!node) return NULL;
node->data = data;
node->next = *list;
return *list = node;
}
// IS EASY TO SWAP THE VALUES
/*
void swap(data_t* a, data_t* b) {
data_t c = *a;
*a = *b;
*b = c;
}
void simple_bubble_sort(node_t** list) {
for(node_t* i = *list; i; i = i->next)
for(node_t* j = *list; j->next; j = j->next)
if(j->data > j->next->data)
swap(&(j->data), &(j->next->data));
}
*/
// MUCH LESS EASY TO SWAP THE NODES
void swap_node(node_t** prev_node_A, node_t** node_A, node_t** node_B) {
node_t *last_node = (*node_B)->next;
node_t *first_node = *node_A;
node_t *second_node = *node_B;
if (prev_node_A) {
(*prev_node_A)->next = second_node;
(*prev_node_A)->next->next = first_node;
(*prev_node_A)->next->next->next = last_node;
} else {
(*node_A) = second_node;
(*node_A)->next = first_node;
(*node_A)->next->next = last_node;
}
}
void simple_bubble_sort(node_t** list) {
for(node_t* i = *list; i->next; i = i->next)
for (node_t *j = *list; j->next->next; j = j->next) {
if (j == *list) {
if (j->data > j->next->data) {
*list = j->next;
swap_node(NULL, &j, &(j->next));
}
}
else {
if (j->next->data > j->next->next->data)
swap_node(&j, &(j->next), &(j->next->next));
}
//printf("%i,%i | %i, %i, %i, %i \n", i->data, j->data, (*list)->data, (*list)->next->data, (*list)->next->next->data, (*list)->next->next->next->data);
//system("pause");
}
}
int main() {
// Create List
node_t** list = list_new();
if (!list)
goto memory_allocation_failure;
// Add values to List
for(int i=0; i<10; i++)
if (!list_push_front(list, i))
goto memory_allocation_failure;
// Print List
for (node_t* node = *list; node != NULL; node = node->next)
printf("%i\n", node->data);
// Swap Test
//swap_node(NULL, &(*list), &((*list)->next));
//swap_node(&(*list), &((*list)->next), &((*list)->next->next));
// Sort List
printf("-- Bubble Sort --\n");
simple_bubble_sort(list);
// Print List
for (node_t* node = *list; node != NULL; node = node->next)
printf("%i\n", node->data);
// Delete List
list_delete(list);
return 0;
// Error Handler
memory_allocation_failure:
printf("Memory Allocation Failure");
return 1;
}
Here is the function swap.
void swap( node_t **current )
{
node_t *tmp = ( *current )->next->next;
( *current )->next->next = *current;
*current = ( *current )->next;
( *current )->next->next = tmp;
}
And here is the function simple_bubble_sort
void simple_bubble_sort( node_t **head )
{
if ( *head )
{
for ( node_t **first = head, *sorted = NULL, *last = sorted;
( *first )->next != last;
last = sorted )
{
sorted = ( *first )->next;
for ( node_t **current = first; ( *current )->next != last; current = &( *current )->next )
{
if ( ( *current )->next->data < ( *current )->data )
{
swap( current );
sorted = ( *current )->next;
}
}
}
}
}
Investigate them.
Pay attention to that the header <malloc.h> is not a standard C header. Instead use the header <stdlib.h>.
You need to revise your current code. For example this function
node_t** list_new() {
node_t** list = malloc(sizeof **list);
if (!list) return NULL;
*list = NULL;
return list;
}
does not make sense it should be removed.
What you need is just to define in main a pointer like
node_t *head = NULL;
And pass it to functions as for example to the function simple_bubble_sort like
simple_bubble_sort( &head );
Or the function list_push_front should be defined like
int list_push_front(node_t** list, data_t data)
{
node_t* node = malloc(sizeof(node_t));
int success = node != NULL;
if ( success )
{
node->data = data;
node->next = *list;
*list = node;
}
return success;;
}

linked list c programming error by inserting new element

I am trying to insert an element but it get the error "Process finished with exit code 11"
struct node {
int key;
struct node *next;
};
struct node* init(){
struct node *head =NULL;
return head;
}
void create(struct node * head,int num) {
struct node * tmp = head;
struct node * prev = NULL;
struct node* new = malloc(sizeof(struct node));
new->key = num;
prev = tmp;
tmp = tmp->next;
while(tmp!= NULL && tmp->key < num){
prev = tmp;
tmp = tmp->next;
}
new->next = tmp;
prev->next = new;
if (tmp== NULL)
head=tmp;
}
int main() {
int num;
struct node* head;
head=init()
printf("Enter data:");
scanf("%d",&num);
create(head,num);
}
i am trying to insert an element into a linked list and the element should be sorted and entered at the same time.can someone tell me that the error is ? i cannot seem to find out the error.
It's not clear what your function create()
void create(struct node * head, int num) {
struct node * tmp = head;
struct node * prev = NULL;
struct node* new = malloc(sizeof(struct node));
new->key = num;
prev = tmp;
tmp = tmp->next;
while (tmp != NULL && tmp->key < num) {
prev = tmp;
tmp = tmp->next;
}
new->next = tmp;
prev->next = new;
if (tmp == NULL)
head = tmp;
}
is supposed to do. You effectively pass it a NULL pointer and return void, so everything it does is meaningless to the outside world.
Thetm starting point for every no bs linked list implementation:
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
typedef struct node_tag {
int value;
struct node_tag *next;
} node_t;
// write functions to encapsulate the data and provide a stable interface:
node_t* node_create_value(int value)
{
node_t *new_node = calloc(1, sizeof *new_node);
if(new_node) new_node->value = value;
return new_node;
}
node_t* node_advance(node_t const *node) { return node->next; }
typedef struct list_tag { // a list usually consists of
node_t *head; // a pointer to the first and
node_t *tail; // a pointer to the last element
// size_t size; // one might want to add that.
} list_t;
list_t list_create(void)
{
list_t list = { NULL, NULL };
return list;
}
// make code based on these functions "speak" for itself:
node_t* list_begin(list_t const *list) { return list->head; }
node_t* list_end (list_t const *list) { return list->tail; }
bool list_is_empty(list_t const *list) { return !list_begin(list); }
// common operations for lists:
node_t* list_push_front(list_t *list, int value)
{
node_t *new_node = node_create_value(value);
if (!new_node)
return NULL;
new_node->next = list->head;
return list->head = new_node;
}
node_t* list_push_back(list_t *list, int value)
{
// push_back on an empty list is push_front:
if (list_is_empty(list))
return list->tail = list_push_front(list, value);
node_t *new_node = node_create_value(value);
if (!new_node)
return NULL;
list->tail->next = new_node;
return list->tail = new_node;
}
node_t* list_insert_after(list_t *list, node_t *node, int value)
{
if (list_end(list) == node)
return list_push_back(list, value);
node_t *new_node = node_create_value(value);
if (!new_node)
return NULL;
new_node->next = node->next;
return node->next = new_node;
}
node_t* list_insert_sorted(list_t *list, int value)
{
// first handle the special cases that don't require iterating the whole list:
if (list_is_empty(list) || value < list_begin(list)->value)
return list_push_front(list, value);
if (value > list_end(list)->value)
return list_push_back(list, value);
// the general (worst) case:
for (node_t *current_node = list_begin(list); node_advance(current_node); current_node = node_advance(current_node))
if (value < node_advance(current_node)->value)
return list_insert_after(list, current_node, value);
return NULL; // should never happen
}
void list_print(list_t const *list)
{
for (node_t *current_node = list_begin(list); current_node; current_node = node_advance(current_node))
printf("%d\n", current_node->value);
}
void list_free(list_t *list)
{
for(node_t *current_node = list_begin(list), *next_node; current_node; current_node = next_node) {
next_node = current_node->next;
free(current_node);
}
}
// user code should not be required to know anything about the inner workings
// of our list:
int main(void)
{
list_t list = list_create();
for (int i = 1; i < 10; i += 2) {
if (!list_push_back(&list, i)) {
list_free(&list);
fputs("Not enough memory :(\n\n", stderr);
return EXIT_FAILURE;
}
}
list_print(&list);
putchar('\n');
for (int i = 0; i < 11; i += 2) {
if (!list_insert_sorted(&list, i)) {
list_free(&list);
fputs("Not enough memory :(\n\n", stderr);
return EXIT_FAILURE;
}
}
list_print(&list);
list_free(&list);
}
Output:
1
3
5
7
9
0
1
2
3
4
5
6
7
8
9
10

Resources