00001 /*! \file issort.c 00002 This file implements sorting by insersion 00003 */ 00004 00005 00006 #include <stdlib.h> 00007 #include <string.h> 00008 #include "sort.h" 00009 00010 00011 00012 00013 /*! \brief Sort data using the insertion method. 00014 \param donnee Pointer to the beginning of the array to sort. 00015 \param nb_elts Number of elements in the array. 00016 \param taille_elt Size in bytes of one element. 00017 \param compare User defined function used to compare two elements of the array. 00018 If you want to sort according to increasing values, then the function <i>compare()</i> should return: 00019 <UL> 00020 <li>1 if <i>cle1 > cle2</i> 00021 <li>0 if <i>cle1 == cle2</i> 00022 <li>-1 if <i>cle1 < cle2</i> 00023 </UL> 00024 If you want to sort according to decreasing values, then the function <i>compare()</i> should return: 00025 <UL> 00026 <li>1 if <i>cle1 < cle2</i> 00027 <li>0 if <i>cle1 == cle2</i> 00028 <li>-1 if <i>cle1 > cle2</i> 00029 </UL> 00030 \return Upon successful completion the function returns 0, otherwise it returns -1 00031 \warning This function is not suitable if you need to sort an inportant number of element. 00032 */ 00033 00034 int issort ( 00035 void *donnee, 00036 int nb_elts, 00037 int taille_elt, 00038 int (*compare)(const void *cle1, const void *cle2) 00039 ) 00040 { 00041 char *tab = donnee; 00042 void *cle; 00043 int i, j; 00044 00045 /* ------------------------------------------------------------ */ 00046 /* Allocate memory */ 00047 /* ------------------------------------------------------------ */ 00048 00049 if ((cle = (char *)malloc(taille_elt)) == NULL) { return -1; } 00050 00051 /* ------------------------------------------------------------ */ 00052 /* Insert a key */ 00053 /* ------------------------------------------------------------ */ 00054 00055 for (j = 1; j < nb_elts; j++) 00056 { 00057 memcpy(cle, &tab[j * taille_elt], taille_elt); 00058 i = j - 1; 00059 00060 /* ---------------------------------------------------------- */ 00061 /* Where to insert the key */ 00062 /* ---------------------------------------------------------- */ 00063 00064 while (i >= 0 && compare(&tab[i * taille_elt], cle) > 0) 00065 { 00066 memcpy(&tab[(i + 1) * taille_elt], &tab[i * taille_elt], taille_elt); 00067 i--; 00068 } 00069 00070 memcpy(&tab[(i + 1) * taille_elt], cle, taille_elt); 00071 } 00072 00073 /* ------------------------------------------------------------ */ 00074 /* Free all allocated memory */ 00075 /* ------------------------------------------------------------ */ 00076 00077 free(cle); 00078 00079 return 0; 00080 } 00081 00082 /*! \example test_sort.c 00083 This file shows how to use the function issort(). 00084 */ 00085 00086 /*! \brief Extended version of the function <i>issort()</i>. This can be used to handle complex data. 00087 \param donnee Pointer to the beginning of the array to sort. 00088 \param nb_elts Number of elements in the array. 00089 \param compare User defined function used to compare two elements of the array. 00090 If you want to sort according to increasing values, then the function <i>compare()</i> should return: 00091 <UL> 00092 <li>1 if <i>cle1 > cle2</i> 00093 <li>0 if <i>cle1 == cle2</i> 00094 <li>-1 if <i>cle1 < cle2</i> 00095 </UL> 00096 If you want to sort according to decreasing values, then the function <i>compare()</i> should return: 00097 <UL> 00098 <li>1 if <i>cle1 < cle2</i> 00099 <li>0 if <i>cle1 == cle2</i> 00100 <li>-1 if <i>cle1 > cle2</i> 00101 </UL> 00102 \param copy_data User defined function used to copy data. <B>The function must take care of memory management.</B> 00103 This function must return: 00104 <UL> 00105 <li>0 upon successful completion. 00106 <li>1 if an error occured. 00107 </UL> 00108 \param init_elem User defined function used to initialize an element. You can specify a NULL pointer if you do not need to initialize 00109 elements. This function must return: 00110 <UL> 00111 <li>0 upon successful completion. 00112 <li>1 if an error occured. 00113 </UL> 00114 This function is called whenever a new element is allocated. 00115 \return Upon successful completion the function returns 0, otherwise it returns -1 00116 \warning This function is not suitable if you need to sort an inportant number of element. 00117 */ 00118 00119 00120 00121 int extended_issort ( 00122 void *donnee, 00123 int nb_elts, 00124 int taille_elt, 00125 int (*compare)(const void *cle1, const void *cle2), 00126 int (*copy_data)(void *src, void *dest), 00127 int (*init_elem)(void *elm) 00128 ) 00129 { 00130 char *tab = donnee; 00131 void *cle; 00132 int i, j; 00133 00134 /* ------------------------------------------------------------ */ 00135 /* Allocate memory */ 00136 /* ------------------------------------------------------------ */ 00137 00138 if ((cle = (char *)malloc(taille_elt)) == NULL) { return -1; } 00139 if (init_elem != NULL) { if (init_elem(cle) == 1) { free(cle); return -1; } } 00140 00141 /* ------------------------------------------------------------ */ 00142 /* Insert a key */ 00143 /* ------------------------------------------------------------ */ 00144 00145 for (j = 1; j < nb_elts; j++) 00146 { 00147 if (copy_data (&tab[j * taille_elt], cle) == 1) { free(cle); return -1; } 00148 i = j - 1; 00149 00150 /* ---------------------------------------------------------- */ 00151 /* Where to insert the key */ 00152 /* ---------------------------------------------------------- */ 00153 00154 while (i >= 0 && compare(&tab[i * taille_elt], cle) > 0) 00155 { 00156 if (copy_data (&tab[i * taille_elt], &tab[(i + 1) * taille_elt]) == 1) { free(cle); return -1; } 00157 i--; 00158 } 00159 00160 if (copy_data (cle, &tab[(i + 1) * taille_elt]) == 1) { free(cle); return -1; } 00161 } 00162 00163 /* ------------------------------------------------------------ */ 00164 /* Free all allocated memory */ 00165 /* ------------------------------------------------------------ */ 00166 00167 free(cle); 00168 00169 return 0; 00170 } 00171 00172 /*! \example test_ext_sort.c 00173 This file shows how to use the function extended_issort(). 00174 */ 00175