I'm trying to sort a linked list using bubble sort algorithm, by changing the references of nodes. I have searched through a lot of books and on the internet, but I have only found sort methods that changes the values from the information part between nodes. What I want to do is sorting by changing the order of traveling the list, not the values between them. Here's my code. PS: The sort algorithm does not work. It's not duplicate of merge sort list, because it's entirely another algorithm.
#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include <stdlib.h>
#define LINESIZE 128
struct Student {
float medie;
char nrMatricol[10];
char *nume;
char facltate[6];
};
struct Nod{
Student stud;
Nod* next;
};
Nod* inserareNodEnd(Nod *l,Student st)
{
Nod *nou = (Nod*)malloc(sizeof(Nod));
nou->next = NULL;//NOU->NEXT=0
nou->stud = st;
if (!l) {
//lista este goala
return nou;
}
else
{
//lista contine un nod
Nod *t = l;
while (t->next) {
t = t->next;
}
t->next = nou;
return l;
}
}
float medieStudenti(Nod *lista) {
float suma=0;
int i=0;
Nod *aux=lista;
while (aux->next) {
aux = aux->next;
suma += aux->stud.medie;
i++;
}
return suma/i;
}
Nod *stergerePrimulNodLista(Nod *l,Student *st) {
if (l) {
Nod *aux = l;
l = l->next;
aux->next = NULL;
*st = aux->stud;
//aux->next = NULL;
free(aux);
}
return l;
}
Nod* sortareLista(Nod *l) {
Nod *i=l;
Nod *j=l;
Nod *aux=l;
Nod *min=l;
min = i;
while (i->next) {
if (i->stud.medie < min->stud.medie) {
min = i;
}
i = i->next;
}
i = l;
int n = 0;
while (i->next) {
j = i->next;
while (j->next) {
if (i->stud.medie > j->stud.medie) {
aux = i->next;
i->next = j->next;
j->next = aux;
}
j = j->next;
}
i = i->next;
}
return min;
//return l;
}
void dezalocare(Nod *lista) {
Nod *aux;
aux = lista;
while (aux->next) {
lista = aux->next;
free(aux->stud.nume);
free(aux);
aux = lista;
}
}
void main()
{
FILE *f;
Student s;
Nod *list=NULL;
f = fopen("fisier.txt", "r");
char fileBuff[LINESIZE], SEPARATORI[] = { "," };
char *token;
while (fgets(fileBuff, LINESIZE, f)) {
token = strtok(fileBuff, SEPARATORI);
strcpy(s.nrMatricol, token);
//extragere token nume student din aceeasi linie
//salvata in file Buff
token = strtok(NULL, SEPARATORI);
s.nume = (char*)malloc(sizeof(char)*strlen(token) + 1);
strcpy(s.nume, token);
token = strtok(NULL, SEPARATORI);
strcpy(s.facltate, token);
//extragere tokeni medie si conversia tokenului la float
token = strtok(NULL, SEPARATORI);
s.medie = atof(token);
list = inserareNodEnd(list, s);
printf("%s %s \n", s.nrMatricol, s.nume);
}
Nod *tmp = list;
while (tmp) {
printf("\nSe afiseaza din lista");
printf("%s %s \n", tmp->stud.nrMatricol, tmp->stud.nume);
tmp = tmp->next;
}
fclose(f);
//determinarea mediei pentru studentii din lista
float media = medieStudenti(list);
printf("\nMedia este %.2f", media);
//sortare lista dupa medie(cu modificarea adreselor de legatura)
//tema dezalocare lista
//tema dezalocari la nivel de aplicatie
printf("\nAcesta este Ionel %s %s \n", s.nrMatricol, s.nume);
// list = stergerePrimulNodLista(list, &s);
tmp = list;
while (tmp) {
printf("\nSe afiseaza din lista");
printf("%s %s \n", tmp->stud.nrMatricol, tmp->stud.nume);
tmp = tmp->next;
}
tmp = list;
while (tmp) {
printf("\nSe afiseaza lista sortata");
printf("%s %s \n", tmp->stud.nrMatricol, tmp->stud.nume);
tmp = tmp->next;
}
dezalocare(list);
}
As requested by original poster, example of a bubble sort for linked list.
Update - removed swap
, using pnEnd (ptr to end of unsorted list) instead.
/* bubble sort linked list */
NODE * SortList(NODE *pHead) /* pHead used as local ptr to start of list */
{
NODE *pEnd = NULL; /* ptr to end of unsorted part of list */
NODE *pnEnd; /* pEnd for next pass */
NODE *pNext; /* ptr to next node */
NODE **ppCurr; /* ptr to ptr to curr node */
if(pHead == NULL) /* return if empty list */
return pHead;
do{
ppCurr = &pHead; /* set ppCurr to start of list */
pnEnd = pHead->next; /* set pnEnd to 2nd node */
while((pNext = (*ppCurr)->next) != pEnd){
if((*ppCurr)->data > pNext->data){ /* if out of order swap */
(*ppCurr)->next = pNext->next;
pnEnd = pNext->next = *ppCurr;
*ppCurr = pNext;
}
ppCurr = &(*ppCurr)->next;
}
pEnd = pnEnd; /* update pEnd since rest of list is sorted */
}while(pEnd != pHead->next);
return pHead;
}