问题
Given this problem:
Write a function that takes two date of birth structures as input and returns -1, 0, 1 if the first parameter is less than, equal to or greater than the second parameter respectively. Using your function, write a recursive mergeSort program to sort the linked list of student records in increasing order of their age (do not use arrays, use linked list only).
here is what I wrote:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*Recursive Merge Sort to sort linked list of students in increasing order
of their age*/
/*A structure dateofbirth is created to store date of birth of each
student*/
struct dateofbirth {
int date;
int month;
int year;
};
/*Another structure student is created whihc contains information about a
student and it is also a nested structure that contains another structure
dateofbirth*/
struct student {
char firstname[64];
struct dateofbirth d;
int height;
float weight;
struct student *next;
};
/*Some pointers are made global as they will be used many a times in the
programs*/
struct student *temp = NULL, *start = NULL, *end = NULL;
/*comparedob will take two dateofbirth structures and compare them which one
is greater */
int comparison(struct dateofbirth d1,struct dateofbirth d2) {
if (d1.year > d2.year)
return 1;
else if (d1.year < d2.year)
return -1;
else if (d1.month > d2.month)
return 1;
else if (d1.month < d2.month)
return -1;
else if (d1.date > d2.date)
return 1;
else if (d1.date < d2.date)
return -1;
else return 0;
}
/*It displays the linked list starting from the first till the last*/
void display() {
temp = start;
while (temp != NULL) {
printf("%s, ", temp->firstname);
if (temp->d.month < 10)
printf("%d0%d%d, ", temp->d.date, temp->d.month, temp->d.year);
else
printf("%d%d%d, ", temp->d.date, temp->d.month, temp->d.year);
printf("%d, ", temp->height);
printf("%.2f\n", temp->weight);
temp = temp->next;
}
}
/*It reads from the file*/
void readdata() {
int a;
if (start == NULL) { /*This case will be implemented when the first record is read
from the file*/
temp = (struct student*) malloc(sizeof(struct student));
if (temp == NULL) {
printf("\nNot enough memory");
}
scanf("%s", (*temp).firstname);
scanf("%d", &a);
(*temp).d.date = a / 1000000;
(*temp).d.month = (a % 1000000) / 10000;
(*temp).d.year = a % 10000;
scanf("%d", &(*temp).height);
scanf("%lf", &(*temp).weight);
temp->next = NULL;
start = temp;
end = temp;
} else { /*For all subsequent records this case will be implemented*/
temp = (struct student*) malloc(sizeof(struct student));
if (temp == NULL) {
printf("\nNot enough memory");
}
scanf("%s", (*temp).firstname);
scanf("%d", &a);
(*temp).d.date = a / 1000000;
(*temp).d.month = (a % 1000000) / 10000;
(*temp).d.year = a % 10000;
scanf("%d", &(*temp).height);
scanf("%lf", &(*temp).weight);
temp->next = NULL;
end->next = temp;
end = temp;
}
}
/*This function will swap two student record with the help of pointers*/
void swap(struct student* s1,struct student* s2) {
struct student s;
strcpy(s.firstname, (*s1).firstname);
strcpy((*s1).firstname, (*s2).firstname);
strcpy((*s2).firstname, s.firstname);
s.d.date = (*s1).d.date;
(*s1).d.date = (*s2).d.date;
(*s2).d.date = s.d.date;
s.d.month = (*s1).d.month;
(*s1).d.month = (*s2).d.month;
(*s2).d.month = s.d.month;
s.d.year = (*s1).d.year;
(*s1).d.year = (*s2).d.year;
(*s2).d.year = s.d.year;
s.height= (*s1).height;
(*s1).height = (*s2).height;
(*s2).height = s.height;
s.weight = (*s1).weight;
(*s1).weight = (*s2).weight;
(*s2).weight = s.weight;
}
/*This function is used to find the middle record in a linked list by making
one pointer move at a double pace than the other*/
void middle(struct student* head, struct student** s1, struct student** s2) {
struct student* x = NULL, *y = NULL;
if (head == NULL || head->next == NULL) {
*s1=head;
*s2=NULL;
} else {
x = head;
y = head->next;
while (y != NULL) {
y=y->next;
if (y != NULL) {
x = x->next;
y = y->next;
}
}
*s1 = head;
*s2 = x->next;
x->next = NULL;
}
}
/*This function will combine both the independently sorted linked lists of
records of student*/
struct student* merge(struct student* a,struct student* b) {
struct student* final = NULL; // final will store the result of merging 'a' and 'b'
if (a == NULL)
return (b);
else if (b == NULL)
return (a);
if (comparison((*a).d, (*(b)).d) == 1) {
final = a;
final->next = merge(a->next, b);
} else {
final=b;
final->next = merge(a, b->next);
}
return (final);
}
/*Recursive merge sort*/
void mergesort(struct student** Ref) {
struct student* base = *Ref; /*Ref is a pointer to pointer which will point to
the starting record so that we do not lose the reference of the starting
record in the process of merging*/
struct student* a = NULL; //Variable pointer
struct student* b = NULL; //Variable pointer
if ((base == NULL) || (base->next == NULL))
return;
middle(base, &a, &b);
mergesort(&a);
mergesort(&b);
*Ref = merge(a,b);
}
void main() {
int m, i;
scanf("%d", &m);
printf("%d\n", m);
for (i = 0; i < m; i++)
readdata();
mergesort(&start);
display();
}
The program is sorting, but the weight
properties reported in the output are changed to zero. Why is that happening?
来源:https://stackoverflow.com/questions/47459941/sorting-a-linked-list-using-merge-sort