Reputation: 91
I am doing a C program to sort the dates the user has entered chronologically using the built-in qsort function. I am using structs. My code however does not sort them properly. Any help? Here is the bit of code that I call in my qsort.
int comparator(const void *p, const void *q)
{
int l3 = ((struct dates *)p)->year;
int r3 = ((struct dates *)q)->year;
if(l3 >= 90 || l3<=99 ){
if(l3 > r3){
return 1;
}
else if(l3 < r3){
return -1;
}
}
else if(l3 > 99){
if(l3 > r3){
return 1;
}
else if(l3 < r3){
return -1;
}
}
int l2 = stringtoInt(((struct dates *)p)->month);
int r2 = stringtoInt(((struct dates *)q)->month);
if (l2 > r2)
{
return 1;
}
else if ( l2 < r2)
{
return -1;
}
int l = ((struct dates *)p)->day;
int r = ((struct dates *)q)->day;
if (l > r)
{
return 1;
}
else if ( l < r)
{
return -1;
}
}
Upvotes: 0
Views: 2415
Reputation: 13
I was working on a schedule maker program so here's the code i have used to sort dates
void LinkedList::appendNode(Node* newNode){
Node *ptr = head;
if (head == NULL){
head = newNode;
}else{
//First compare years if newNode year is less than 1st node if yes, interchange them
if(ptr->year > newNode->year){
newNode->link = head;
head = newNode;
}
//if years are same then compare months
else if(ptr->year == newNode->year){
//compare if newNode month is less than the 1st node in list if yes, interchange them
if(ptr->month > newNode->month){
newNode->link = head;
head = newNode;
}
//if months of both are equal compare dates
else if(ptr->month == newNode->month){
//compare if date of newNode is smaller than the 1st node. If yes, interchange them
if(ptr->date > newNode->date){
newNode->link = head;
head = newNode;
}
//if dates are same then, check time
else if(ptr->date == newNode->date){
//compare the hour
if(ptr->hour > newNode->hour){
newNode->link = head;
head = newNode;
}
//if hour is same check time
else if(ptr->hour == newNode->hour){
//compare the minute
if(ptr->min > newNode->min){
newNode->link = head;
head = newNode;
}
else if(ptr->min == newNode->min){
newNode->link = head;
head = newNode;
}
//if minute in newNode is greater then traverse and place it accordingly
else{
ptr = head;
//traverse the link till the next node is greater than the newNode
while(ptr->link != NULL){
if(ptr->link->year > newNode->year)
break;
else if(ptr->link->year == newNode->year && ptr->link->month > newNode->month)
break;
else if(ptr->link->year == newNode->year && ptr->link->month > newNode->month && ptr->link->date > newNode->date)
break;
else if(ptr->link->year==newNode->year&&ptr->link->month>newNode->month&&ptr->link->date==newNode->date&&ptr->link->hour>newNode->hour)
break;
else if(ptr->link->year==newNode->year&&ptr->link->month>newNode->month&&ptr->link->date==newNode->date&&ptr->link->hour==newNode->hour&&ptr->link->min>newNode->min)
break;
ptr = ptr->link;
}
newNode->link = ptr->link;
ptr->link = newNode;
}
}
//if hour in newNode is greater then traverse and place it accordingly
else{
ptr = head;
//traverse the link till the next node is greater than the newNode
while(ptr->link != NULL){
if(ptr->link->year > newNode->year)
break;
else if(ptr->link->year == newNode->year && ptr->link->month > newNode->month)
break;
else if(ptr->link->year == newNode->year && ptr->link->month > newNode->month && ptr->link->date > newNode->date)
break;
else if(ptr->link->year==newNode->year&&ptr->link->month>newNode->month&&ptr->link->date==newNode->date&&ptr->link->hour>newNode->hour)
break;
else if(ptr->link->year==newNode->year&&ptr->link->month>newNode->month&&ptr->link->date==newNode->date&&ptr->link->hour==newNode->hour&&ptr->link->min>newNode->min)
break;
ptr = ptr->link;
}
newNode->link = ptr->link;
ptr->link = newNode;
}
}
//else if newNode date is greater
else{
ptr = head;
//traverse the link till the next node is greater than the newNode
while(ptr->link != NULL){
if(ptr->link->year > newNode->year)
break;
else if(ptr->link->year == newNode->year && ptr->link->month > newNode->month)
break;
else if(ptr->link->year == newNode->year && ptr->link->month > newNode->month && ptr->link->date > newNode->date)
break;
ptr = ptr->link;
}
newNode->link = ptr->link;
ptr->link = newNode;
}
}
//else if the month of newNode is greater
else{
ptr = head;
//traverse the link till the next node is greater than the newNode
while(ptr->link != NULL){
if(ptr->link->year > newNode->year)
break;
else if(ptr->link->year == newNode->year && ptr->link->month > newNode->month)
break;
else if(ptr->link->year == newNode->year && ptr->link->month > newNode->month && ptr->link->date > newNode->date)
break;
ptr = ptr->link;
}
newNode->link = ptr->link;
ptr->link = newNode;
}
}
//else if the year of year of newNode is greater
else{
ptr = head;
//traverse the link till the next node is greater than the newNode
while(ptr->link != NULL){
if(ptr->link->year > newNode->year)
break;
else if(ptr->link->year == newNode->year && ptr->link->month > newNode->month)
break;
else if(ptr->link->year == newNode->year && ptr->link->month > newNode->month && ptr->link->date > newNode->date)
break;
ptr = ptr->link;
}
newNode->link = ptr->link;
ptr->link = newNode;
}
}
}
Upvotes: 0
Reputation: 16540
The posted code seems to be assuming that the year fields are only 2 digits. It that a valid assumption?
this line:
else if(l3 > 99){
is not correct, because a 2 digit year 'should' never by greater than 99.
(I would suggest using 4 digit years, but such is your data design choice)
However, it seems that if the year is not in the range 90...99 inclusive, then it has to be in the new century
so no need to be checking if the year is > 99, just assume it is in the new century.
What happens when the one-date is in the prior century (90...99) and the other-date is in the next century? The code does not seem to be accounting for that condition.
Upvotes: 0
Reputation: 174
Your first if construct,
if (l3 >= 90 || l3 <= 99)
will always evaluate to true, so the following else if
will never be entered. I'm assuming the condition is meant to be l3 >= 90 && l3 <= 99
, although if that's the case, since the following else if
has the same body, you could merge them into a single if statement, if (l3 >= 90)
.
Furthermore, you aren't handling the case where l3 < 90
, so in that case your comparator will ignore year and move on to comparing by month and then day.
I would also add an explicit return 0
at the end of the function, when the dates are determined to be equal.
Upvotes: 3