Last active
November 4, 2016 07:05
-
-
Save nishidy/9e183e4797db6f183537ddb5fb66767d to your computer and use it in GitHub Desktop.
Sort function optimized with double pointer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <time.h> | |
#include <sys/time.h> | |
typedef unsigned int uint; | |
typedef unsigned long ulong; | |
typedef struct { | |
char first_name[32]; | |
char last_name[32]; | |
unsigned int age; | |
} Data; | |
ulong alloc_size = 0; | |
uint alloc_count = 0; | |
void* _malloc(size_t size){ | |
alloc_size += size; | |
alloc_count ++; | |
return malloc(size); | |
} | |
double print_time(struct timeval *s, struct timeval *e){ | |
int si = (s->tv_sec%1000000)*1000+s->tv_usec/1000; | |
int ei = (e->tv_sec%1000000)*1000+e->tv_usec/1000; | |
return (double)(ei-si)/1000.0; | |
} | |
void print(uint size, Data** data){ | |
int i; | |
printf("Let's print %d data.\n",size); | |
for(i=0;i<size;i++){ | |
printf("%d\n",(*(data+i))->age); | |
} | |
} | |
void _print(uint size, Data* data){ | |
int i; | |
printf("Let's print %d data.\n",size); | |
for(i=0;i<size;i++){ | |
printf("%d\n",(data+i)->age); | |
} | |
} | |
void _sort(uint size, Data* data){ | |
if(size==1) return; | |
Data* all = (Data*)_malloc(sizeof(Data)*(size-1)); | |
Data* small = all; | |
Data* large; | |
uint smalls = 0; | |
uint larges = 0; | |
Data pivot = *data; // This must not be pointer to data | |
int i; | |
for(i=1;i<size;i++){ | |
if((data+i)->age<pivot.age){ | |
*(small+smalls) = *(data+i); | |
smalls++; | |
} | |
} | |
large = all+smalls; | |
for(i=1;i<size;i++){ | |
if((data+i)->age>=pivot.age){ | |
*(large+larges) = *(data+i); | |
larges++; | |
} | |
} | |
if(smalls) | |
_sort(smalls,small); | |
if(larges) | |
_sort(larges,large); | |
memcpy(data,small,sizeof(Data)*smalls); | |
memcpy(data+smalls,&pivot,sizeof(Data)*1); | |
memcpy(data+smalls+1,large,sizeof(Data)*larges); | |
free(all); | |
} | |
void sort(uint size, Data** data){ | |
if(size==1) return; | |
Data** all = (Data**)_malloc(sizeof(Data*)*(size-1)); | |
Data** small = all; | |
Data** large; | |
uint smalls = 0; | |
uint larges = 0; | |
Data* pivot = *data; | |
int i; | |
for(i=1;i<size;i++){ | |
if((*(data+i))->age<pivot->age){ | |
*(small+smalls) = *(data+i); | |
smalls++; | |
} | |
} | |
large = all+smalls; | |
for(i=1;i<size;i++){ | |
if((*(data+i))->age>=pivot->age){ | |
*(large+larges) = *(data+i); | |
larges++; | |
} | |
} | |
if(smalls) | |
sort(smalls,small); | |
if(larges) | |
sort(larges,large); | |
memcpy(data,small,sizeof(Data*)*smalls); | |
memcpy(data+smalls,&pivot,sizeof(Data*)*1); | |
memcpy(data+smalls+1,large,sizeof(Data*)*larges); | |
free(all); | |
} | |
void create_data(uint size, Data* data){ | |
int i; | |
for(i=0;i<size;i++){ | |
(data+i)->age = rand()%size; | |
} | |
} | |
int assert(uint size, Data** adata){ | |
int i,age=0; | |
for(i=0;i<size;i++){ | |
if(age<=(*(adata+i))->age){ | |
age=(*(adata+i))->age; | |
}else{ | |
return 0; | |
} | |
} | |
return 1; | |
} | |
int _assert(uint size, Data* adata){ | |
int i,age=0; | |
for(i=0;i<size;i++){ | |
if(age<=(adata+i)->age){ | |
age=(adata+i)->age; | |
}else{ | |
return 0; | |
} | |
} | |
return 1; | |
} | |
int compare_data(const void *a, const void *b) | |
{ | |
return ((Data*)a)->age - ((Data*)b)->age; | |
} | |
int main(int argc, char* argv[]) | |
{ | |
int i,size; | |
struct timeval s, e; | |
size = atoi(argv[1]); | |
srand((unsigned)time(NULL)); | |
Data* data = (Data*)malloc(sizeof(Data)*size); | |
create_data(size,data); | |
Data* orig_data = (Data*)malloc(sizeof(Data)*size); | |
memcpy(orig_data,data,sizeof(Data)*size); | |
Data** adata = (Data**)malloc(sizeof(Data*)*size); | |
for(i=0;i<size;i++) | |
*(adata+i) = data+i; | |
printf("Size of Data struct : %lu\n",sizeof(Data)); | |
printf("Size of a pointer : %lu\n",sizeof(Data*)); | |
printf("(Size of short: %lu)\n",sizeof(short)); | |
printf("(Size of int: %lu)\n",sizeof(int)); | |
printf("(Size of long: %lu)\n",sizeof(long)); | |
printf("\n"); | |
alloc_size = 0; | |
alloc_count = 0; | |
gettimeofday(&s,NULL); | |
sort(size,adata); | |
gettimeofday(&e,NULL); | |
printf("Quick sort (double pointer): %.2lf sec.\n",print_time(&s,&e)); | |
printf("%luMB,%u\n",alloc_size/(1024*1024),alloc_count); | |
if(assert(size,adata)){ | |
printf("Good. Sorted.\n"); | |
}else{ | |
printf("Bad. Not Sorted...\n"); | |
print(10,adata); | |
return -1; | |
} | |
printf("\n"); | |
alloc_size = 0; | |
alloc_count = 0; | |
gettimeofday(&s,NULL); | |
_sort(size,data); | |
gettimeofday(&e,NULL); | |
printf("Quick sort : %.2lf sec.\n",print_time(&s,&e)); | |
printf("%luMB,%u\n",alloc_size/(1024*1024),alloc_count); | |
if(_assert(size,data)){ | |
printf("Good. Sorted.\n"); | |
}else{ | |
printf("Bad. Not Sorted...\n"); | |
_print(10,data); | |
return -1; | |
} | |
printf("\n"); | |
memcpy(data,orig_data,sizeof(Data)*size); | |
gettimeofday(&s,NULL); | |
qsort(data,size,sizeof(Data),compare_data); | |
gettimeofday(&e,NULL); | |
printf("Quick sort (library function) : %.2lf sec.\n",print_time(&s,&e)); | |
if(_assert(size,data)){ | |
printf("Good. Sorted.\n"); | |
}else{ | |
printf("Bad.Not Sorted...\n"); | |
_print(10,data); | |
return -1; | |
} | |
printf("\n"); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment