For starters there is a typo
typedef struct node {
int code;
char name[40];
char job[40];
int salary;
struct nodo *next;
^^^^
struct nodo *prev;
^^^^
} node;
There shall be
typedef struct node {
int code;
char name[40];
char job[40];
int salary;
struct node *next;
^^^^
struct node *prev;
^^^^
} node;
Secondly, if you want to sort a list then you should sort the order of its nodes not swap values of data members of nodes. For example in main there can be declared a pointer to some node. If you will sort the list by swapping values of data members of nodes then the pointer will be invalid because data members of the pointed node was changed.
Thirdly, You should place all data members except the pointers next and prev in a separate structure. In this case function declarations will look much simpler because instead of passing several initializers to functions you will need to pass only one object of the structure type.
For example
typedef struct Person
{
int code;
char name[N];
char job[N];
int salary;
} Person;
typedef struct Node
{
Person person;
struct Node *prev;
struct Node *next;
} Node;
At last if you deal with a doubly-linked list then it is supposed that you can add new nodes to the beginning and to the end of the list. It means that you should keep two pointers: one will point to the first node of the list and other - to the last node of the list. A consequence of this is that you should declare one more structure that will describe the list like for example
typedef struct List
{
Node *head;
Node *tail;
} List;
Now when all is prepared it is time to show how the method bubble sort can be applied to such a list.
Here is a demonstrative program.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
enum { N = 40 };
typedef struct Person
{
int code;
char name[N];
char job[N];
int salary;
} Person;
typedef struct Node
{
Person person;
struct Node *prev;
struct Node *next;
} Node;
typedef struct List
{
Node *head;
Node *tail;
} List;
int push_back( List *list, const Person *person )
{
Node *new_node = malloc( sizeof( Node ) );
int success = new_node != NULL;
if ( success )
{
new_node->person = *person;
new_node->prev = list->tail;
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 display( const List *list )
{
for ( Node *current = list->head; current != NULL; current = current->next )
{
printf( "code = %d, name = %s, job = %s, salary = %d\n",
current->person.code, current->person.name,
current->person.job, current->person.salary );
}
}
void swap( Node **current )
{
Node *tmp = *current;
*current = ( *current )->next;
tmp->next = ( *current )->next;
( *current )->next = tmp;
( *current )->prev = tmp->prev;
tmp->prev = *current;
if ( tmp->next != NULL )
{
tmp->next->prev = tmp;
}
}
void clear( List *list )
{
while ( list->head != NULL )
{
Node *current = list->head;
list->head = list->head->next;
free( current );
}
list->tail = list->head;
}
void sort( List *list, int cmp( const void *, const void * ) )
{
if ( list->head != NULL )
{
int first_iteration = 1;
for ( Node **first = &list->head, *sorted = NULL, *last = NULL;
( *first )->next != last;
last = sorted )
{
Node **current = first;
sorted = ( *first )->next;
for ( ; ( *current )->next != last; current = &( *current )->next )
{
if ( cmp( &( *current )->person, &( *current )->next->person ) > 0 )
{
swap( current );
sorted = ( *current )->next;
}
}
if ( first_iteration )
{
list->tail = *current;
first_iteration = 0;
}
}
}
}
int cmp_by_salary( const void *a, const void *b )
{
const Person *left = a;
const Person *right = b;
return ( right->salary < left->salary ) - ( left->salary < right->salary );
}
int cmp_by_code( const void *a, const void *b )
{
const Person *left = a;
const Person *right = b;
return ( right->code < left->code ) - ( left->code < right->code );
}
int cmp_by_name( const void *a, const void *b )
{
const Person *left = a;
const Person *right = b;
return strcmp( left->name, right->name );
}
int main(void)
{
List list = { .head = NULL, .tail = NULL };
Person person[] =
{
{ .code = 1, .name = "RaCo", .job = "programmer", .salary = 1000 },
{ .code = 2, .name = "Another RaCo", .job = "programmer", .salary = 500 },
{ .code = 3, .name = "One more RaCo", .job = "programmer", .salary = 1500 },
};
const size_t n = sizeof( person ) / sizeof( *person );
puts( "Original list:" );
for ( size_t i = 0; i < n; i++ )
{
push_back( &list, person + i );
}
display( &list );
putchar( '\n' );
sort( &list, cmp_by_salary );
puts( "list sorted by salary:" );
display( &list );
putchar( '\n' );
sort( &list, cmp_by_name );
puts( "list sorted by name:" );
display( &list );
putchar( '\n' );
sort( &list, cmp_by_code );
puts( "list sorted by code:" );
display( &list );
putchar( '\n' );
printf( "Debug output. The pointer tail points to %s\n", list.tail->person.name );
clear( &list );
return 0;
}
The program output is
Original list:
code = 1, name = RaCo, job = programmer, salary = 1000
code = 2, name = Another RaCo, job = programmer, salary = 500
code = 3, name = One more RaCo, job = programmer, salary = 1500
list sorted by salary:
code = 2, name = Another RaCo, job = programmer, salary = 500
code = 1, name = RaCo, job = programmer, salary = 1000
code = 3, name = One more RaCo, job = programmer, salary = 1500
list sorted by name:
code = 2, name = Another RaCo, job = programmer, salary = 500
code = 3, name = One more RaCo, job = programmer, salary = 1500
code = 1, name = RaCo, job = programmer, salary = 1000
list sorted by code:
code = 1, name = RaCo, job = programmer, salary = 1000
code = 2, name = Another RaCo, job = programmer, salary = 500
code = 3, name = One more RaCo, job = programmer, salary = 1500
Debug output. The pointer tail points to One more RaCo
As you can see using the same one function sort you can sort the list by any data member of the structure Person. You need not to write a new sorting function each time when the sorting criteria must be changed.
If you need to sort the list for example by data member salary in the descending order then just exchange variables in the return statement of comparison function
int cmp_by_salary( const void *a, const void *b )
{
const Person *left = a;
const Person *right = b;
return ( right->salary < left->salary ) - ( left->salary < right->salary );
}
like
int cmp_by_salary_desc( const void *a, const void *b )
{
const Person *left = a;
const Person *right = b;
return ( left->salary < right->salary ) - ( right->salary < left->salary );
}
and call the function sort as
sort( &list, cmp_by_salary_desc );
node *temp, usenode temp. Then copy everything into thetempstruct like this:temp.salary = ptr1->salary,strcpy(temp.name, ptr1->name), etc.qsortto sort the array, then rebuild the list using the sorted array. If you don't want to use any temporary storage, then you'll need to write your own merge sort or quicksort or something similar.