Subversion Repositories programming

Rev

Rev 85 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 85 Rev 86
Line 2... Line 2...
2
 * Started on: 05-20-2005
2
 * Started on: 05-20-2005
3
 * Due Date: 06-10-2005
3
 * Due Date: 06-10-2005
4
 * CS331 Project #2
4
 * CS331 Project #2
5
 */
5
 */
6
 
6
 
-
 
7
 
-
 
8
/* standard headers */
7
#include <stdio.h>
9
#include <stdio.h>
8
#include <stdlib.h>
10
#include <stdlib.h>
9
#include <time.h>
11
#include <time.h>
10
 
12
 
11
void mergesort (int array[], unsigned long size);
13
/* broken-out code for common things */
12
void mergesort_rec (int A[], unsigned long min, unsigned long max);
-
 
13
void merge (int A[], unsigned long asize, int B[], unsigned long bsize);
-
 
14
void swap (int *left, int *right);
14
#include "sorts.c"
15
void printarray (int array[], unsigned long size);
-
 
16
void randomfill (int array[], unsigned long size);
-
 
17
int partition (int array[], unsigned long left, unsigned long right);
-
 
18
void copyarray (int src[], int dst[], unsigned long size);
-
 
19
void copyarray_partial (int src[], int dst[], unsigned long src_left,
-
 
20
        unsigned long src_right);
15
#include "timing.c"
21
int* create_array (unsigned long size);
16
#include "arrays.c"
-
 
17
 
22
 
18
 
-
 
19
/* function prototypes */
-
 
20
void randomfill (int array[], unsigned long size);
23
int kth_smallest_method1 (int src_array[], unsigned long size, unsigned long position);
21
int kth_smallest_method1 (int src_array[], unsigned long size, unsigned long position);
24
int kth_smallest_method2 (int src_array[], unsigned long size, unsigned long position);
22
int kth_smallest_method2 (int src_array[], unsigned long size, unsigned long position);
25
int kth_smallest_method3 (int src_array[], unsigned long size, unsigned long position);
23
int kth_smallest_method3 (int src_array[], unsigned long size, unsigned long position);
26
int kth_smallest_method4 (int src_array[], unsigned long size, unsigned long position);
24
int kth_smallest_method4 (int src_array[], unsigned long size, unsigned long position);
27
 
25
 
28
void startclock (void);
-
 
29
void stopclock (void);
-
 
30
void printtimetaken (char *funcname);
-
 
31
 
-
 
32
 
-
 
33
/* global timeval for timing the function calls */
-
 
34
struct timeval start_time, end_time, lapsed;
-
 
35
 
26
 
36
int main (void)
27
int main (void)
37
{
28
{
38
    /* create new random seed */
29
    /* create new random seed */
39
    srand((unsigned)time(NULL));
30
    srand((unsigned)time(NULL));
40
 
31
 
41
    unsigned long size, kth_pos;
32
    unsigned long size, kth_pos;
42
    int* array;
33
    int *array;
43
    int i;
34
    int i;
44
    
35
    
45
    for (size=1000000; size<=10000000; size+=1000000)
36
    for (size=1000000; size<=2000000; size+=1000000)
46
    {
37
    {
47
        array = create_array (size);
38
        array = create_array (size);
48
 
39
 
49
        /* fill the array with random values */
40
        /* fill the array with random values */
50
        randomfill (array, size);
41
        randomfill (array, size);
Line 59... Line 50...
59
                kth_pos=size/2;
50
                kth_pos=size/2;
60
            else if (i==3)
51
            else if (i==3)
61
                kth_pos=3*size/4;
52
                kth_pos=3*size/4;
62
            else
53
            else
63
                kth_pos=size-1;
54
                kth_pos=size-1;
-
 
55
 
64
            /* header */
56
            /* header */
65
            printf ("Running with size=%lu (%.3fMB) kth_pos=%lu...\n",
57
            printf ("Running with size=%lu (%.3fMB) kth_pos=%lu...\n",
66
                    size, (size*4.0)/(1024*1024), kth_pos);
58
                    size, (size*4.0)/(1024*1024), kth_pos);
67
        
59
        
68
            /* run method1 */
60
            /* run method1 */
Line 94... Line 86...
94
            printtimetaken("Method4");
86
            printtimetaken("Method4");
95
            
87
            
96
            printf ("\n\n");
88
            printf ("\n\n");
97
        }
89
        }
98
        
90
        
99
        free (array); array = NULL;
91
        array = free_array (array);
100
    }
92
    }
101
 
93
 
102
    return 0;
94
    return 0;
103
}
95
}
104
 
96
 
105
/* Mergesort an array
-
 
106
 * Sets up the correct parameters and hands off the work to
-
 
107
 * mergesort_rec()
-
 
108
 * 
-
 
109
 * Complexity: O(n*lgn)
-
 
110
 */
-
 
111
void mergesort (int array[], unsigned long size)
-
 
112
{
-
 
113
    mergesort_rec (array, 0, size-1);
-
 
114
}
-
 
115
 
-
 
116
/* The actual mergesort call */
-
 
117
void mergesort_rec (int A[], unsigned long min, unsigned long max)
-
 
118
{
-
 
119
    unsigned long mid = (min+max)/2;
-
 
120
    unsigned long lowerCount = mid - min + 1;
-
 
121
    unsigned long upperCount = max - mid;
-
 
122
 
-
 
123
    if (max == min)
-
 
124
        return;
-
 
125
 
-
 
126
    mergesort_rec (A, min, mid);
-
 
127
    mergesort_rec (A, mid+1, max);
-
 
128
    merge (A+min, lowerCount, A+mid+1, upperCount);
-
 
129
}
-
 
130
 
-
 
131
/* merge two arrays together
-
 
132
 *
-
 
133
 * Complexity: O(n)
-
 
134
 */
-
 
135
void merge(int A[], unsigned long asize, int B[], unsigned long bsize)
-
 
136
{
-
 
137
    unsigned long ai, bi, ci, i;
-
 
138
    int *C;
-
 
139
    unsigned long csize = asize+bsize;
-
 
140
 
-
 
141
    C = create_array (csize);
-
 
142
 
-
 
143
    ai = 0;
-
 
144
    bi = 0;
-
 
145
    ci = 0;
-
 
146
   
-
 
147
    while ((ai < asize) && (bi < bsize)) 
-
 
148
    {
-
 
149
        if (A[ai] <= B[bi])
-
 
150
        {
-
 
151
            C[ci] = A[ai];
-
 
152
            ci++; ai++;
-
 
153
        }
-
 
154
        else
-
 
155
        {
-
 
156
            C[ci] = B[bi];
-
 
157
            ci++; bi++;
-
 
158
        }
-
 
159
    }
-
 
160
 
-
 
161
    if (ai >= asize)
-
 
162
        for (i = ci; i < csize; i++, bi++)
-
 
163
            C[i] = B[bi];
-
 
164
        else if (bi >= bsize)
-
 
165
            for (i = ci; i < csize; i++, ai++)
-
 
166
                C[i] = A[ai];
-
 
167
 
-
 
168
        for (i = 0; i < csize; i++)
-
 
169
            A[i] = C[i];
-
 
170
 
-
 
171
    free (C);
-
 
172
}
-
 
173
 
-
 
174
/* swap two values */
-
 
175
void swap (int *left, int *right)
-
 
176
{
-
 
177
    int temp;
-
 
178
    temp = *left;
-
 
179
    *left = *right;
-
 
180
    *right = temp;
-
 
181
}
-
 
182
 
-
 
183
/* print out the contents of the array
-
 
184
 * used for debugging mainly
-
 
185
 */
-
 
186
void printarray (int array[], unsigned long size)
-
 
187
{
-
 
188
    unsigned long i;
-
 
189
       
-
 
190
    printf("Printing %lu elements\n", size);
-
 
191
        
-
 
192
    for (i=0; i<size; i++)
-
 
193
        printf("%d ", array[i]);
-
 
194
 
-
 
195
    printf("\n");
-
 
196
}
-
 
197
 
-
 
198
/* fill the array with random numbers in
97
/* fill the array with random numbers in
199
 * the range 0-32767
98
 * the range 0-32767
200
 */
99
 */
201
void randomfill (int array[], unsigned long size)
100
void randomfill (int array[], unsigned long size)
202
{
101
{
Line 204... Line 103...
204
        
103
        
205
    for (i=0; i<size; i++)
104
    for (i=0; i<size; i++)
206
        array[i] = rand() % 32768;
105
        array[i] = rand() % 32768;
207
}
106
}
208
 
107
 
209
/* partition from quicksort
-
 
210
 * this partitions an array around the pivot value,
-
 
211
 * which is found in array[left].
-
 
212
 *
-
 
213
 * All values less than the pivot are on the left
-
 
214
 * All values more than the pivot are on the right
-
 
215
 *
-
 
216
 * Complexity: O(n)
-
 
217
 */
-
 
218
int partition (int array[], unsigned long left, unsigned long right)
-
 
219
{
-
 
220
    unsigned long i, last, pivot;
-
 
221
 
-
 
222
    pivot = array[left];
-
 
223
    last = left;
-
 
224
        
-
 
225
    for (i=left+1; i<=right; i++)
-
 
226
        if (array[i] < pivot)
-
 
227
        {
-
 
228
           last++;
-
 
229
           swap (&array[last], &array[i]);
-
 
230
        }
-
 
231
 
-
 
232
    swap (&array[left], &array[last]);
-
 
233
    return last;
-
 
234
}
-
 
235
 
-
 
236
/* start the clock (for timing) */
-
 
237
void startclock (void)
-
 
238
{
-
 
239
    gettimeofday(&start_time, NULL);
-
 
240
}
-
 
241
 
-
 
242
/* stop the clock (for timing) */
-
 
243
void stopclock (void)
-
 
244
{
-
 
245
    gettimeofday(&end_time, NULL);
-
 
246
}
-
 
247
 
-
 
248
/* print the time taken, in milliseconds = seconds / 1000 */
-
 
249
void printtimetaken (char *funcname)
-
 
250
{
-
 
251
    double total_usecs = (end_time.tv_sec-start_time.tv_sec) * 1000000.0
-
 
252
                       + (end_time.tv_usec-start_time.tv_usec);
-
 
253
 
-
 
254
    printf("%s : %.3lf milliseconds\n", funcname, total_usecs/1000.0);
-
 
255
}
-
 
256
 
-
 
257
/* copy the src[] to dst[] */
-
 
258
void copyarray (int src[], int dst[], unsigned long size)
-
 
259
{
-
 
260
    unsigned long i;
-
 
261
 
-
 
262
    for (i=0; i<size; i++)
-
 
263
        dst[i] = src[i];
-
 
264
}
-
 
265
 
-
 
266
void copyarray_partial (int src[], int dst[], unsigned long src_left, 
-
 
267
        unsigned long src_right)
-
 
268
{
-
 
269
    unsigned long i, j;
-
 
270
 
-
 
271
    for (i=src_left, j=0; i<=src_right; i++, j++)
-
 
272
        dst[j] = src[i];
-
 
273
}
-
 
274
 
-
 
275
/* Find the kth smallest element in the array (starting from zero)
108
/* Find the kth smallest element in the array (starting from zero)
276
 *
109
 *
277
 * This uses the method of sorting the list, then picking
110
 * This uses the method of sorting the list, then picking
278
 * the correct element
111
 * the correct element
279
 */
112
 */
Line 287... Line 120...
287
    copyarray (src_array, array, size);
120
    copyarray (src_array, array, size);
288
    
121
    
289
    mergesort (array, size);
122
    mergesort (array, size);
290
 
123
 
291
    retval = array[position];
124
    retval = array[position];
292
    free (array); array = NULL;
125
    array = free_array (array);
293
    
126
    
294
    return retval;
127
    return retval;
295
}
128
}
296
 
129
 
297
/* Find the kth smallest element in the array (starting from zero)
130
/* Find the kth smallest element in the array (starting from zero)
Line 321... Line 154...
321
            right = pivotpos - 1;
154
            right = pivotpos - 1;
322
    }
155
    }
323
    while (pivotpos != position);
156
    while (pivotpos != position);
324
 
157
 
325
    retval = array[position];
158
    retval = array[position];
326
    free (array); array = NULL;
159
    array = free_array (array);
327
    
160
    
328
    return retval;
161
    return retval;
329
}
162
}
330
 
163
 
331
int kth_smallest_method3 (int src_array[], unsigned long size, unsigned long position)
164
int kth_smallest_method3 (int src_array[], unsigned long size, unsigned long position)
Line 345... Line 178...
345
 
178
 
346
    /* base case */
179
    /* base case */
347
    if (pivotpos == position)
180
    if (pivotpos == position)
348
    {
181
    {
349
        retval = array[position];
182
        retval = array[position];
350
        free (array); array = NULL;
183
        array = free_array (array);
351
 
184
 
352
        return retval;
185
        return retval;
353
    }
186
    }
354
    
187
    
355
    /* throw away left side */
188
    /* throw away left side */
Line 367... Line 200...
367
    temparray = create_array (right-left+1);
200
    temparray = create_array (right-left+1);
368
    copyarray_partial (array, temparray, left, right);
201
    copyarray_partial (array, temparray, left, right);
369
 
202
 
370
    retval = kth_smallest_method3 (temparray, right-left+1, newpos);
203
    retval = kth_smallest_method3 (temparray, right-left+1, newpos);
371
 
204
 
372
    free (temparray); temparray = NULL;
205
    temparray = free_array (temparray);
373
    free (array); array = NULL;
206
    array = free_array (array);
374
    
207
    
375
    return retval;
208
    return retval;
376
}
209
}
377
 
210
 
378
int kth_smallest_method4 (int src_array[], unsigned long size, unsigned long position)
211
int kth_smallest_method4 (int src_array[], unsigned long size, unsigned long position)
Line 390... Line 223...
390
    copyarray (src_array, array, size);
223
    copyarray (src_array, array, size);
391
 
224
 
392
    /* base case */
225
    /* base case */
393
    if (size <= group_size)
226
    if (size <= group_size)
394
    {
227
    {
395
        mergesort (array, size);
228
        insertsort (array, size);
396
        retval = array[position];
229
        retval = array[position];
397
 
230
 
398
        free (array); array = NULL;
231
        array = free_array (array);
399
 
232
 
400
        return retval;
233
        return retval;
401
    }
234
    }
402
    
235
    
403
    /* get the array of medians */
236
    /* get the array of medians */
Line 405... Line 238...
405
    temparray = create_array (group_size);
238
    temparray = create_array (group_size);
406
    
239
    
407
    for (i=0; i<num_groups; i++)
240
    for (i=0; i<num_groups; i++)
408
    {
241
    {
409
        copyarray_partial (array, temparray, left, right);
242
        copyarray_partial (array, temparray, left, right);
410
        mergesort (temparray, group_size);
243
        insertsort (temparray, group_size);
411
        medianarray[i] = temparray[group_size/2];
244
        medianarray[i] = temparray[group_size/2];
412
        left = right + 1;
245
        left = right + 1;
413
        right = left + group_size - 1;
246
        right = left + group_size - 1;
414
    }
247
    }
415
 
248
 
416
    free (temparray); temparray = NULL;
249
    temparray = free_array (temparray);
417
    
250
    
418
    /* find the median of medians */
251
    /* find the median of medians */
419
    retval = kth_smallest_method4 (medianarray, num_groups, num_groups/2);
252
    retval = kth_smallest_method4 (medianarray, num_groups, num_groups/2);
420
 
253
 
421
    /* move the mm to the 0th position in the array (for partition) */
254
    /* move the mm to the 0th position in the array (for partition) */
Line 444... Line 277...
444
        temparray = create_array (size-(pivotpos+1));
277
        temparray = create_array (size-(pivotpos+1));
445
        copyarray_partial (array, temparray, pivotpos+1, size-1);
278
        copyarray_partial (array, temparray, pivotpos+1, size-1);
446
        retval = kth_smallest_method4 (temparray, size-(pivotpos+1), position-(pivotpos+1));
279
        retval = kth_smallest_method4 (temparray, size-(pivotpos+1), position-(pivotpos+1));
447
    }
280
    }
448
    
281
    
449
    free (array); array = NULL;
282
    array = free_array (array);
450
    free (medianarray); medianarray = NULL;
283
    medianarray = free_array (medianarray);
451
    if (temparray != NULL)
284
    if (temparray != NULL)
452
    {
285
    {
453
        free (temparray); temparray = NULL;
286
        temparray = free_array (temparray);
454
    }
287
    }
455
 
288
 
456
    return retval;
289
    return retval;
457
}
290
}
458
 
291
 
459
int* create_array (unsigned long size)
-
 
460
{
-
 
461
    int *array;
-
 
462
 
-
 
463
    if ( (array = (int*) malloc (size*sizeof(int))) == NULL)
-
 
464
    {
-
 
465
        printf ("Out of memory allocating array of size=%lu\n", size);
-
 
466
        printf ("Exiting...");
-
 
467
        exit (1);
-
 
468
    }
-
 
469
 
-
 
470
    return array;
-
 
471
}
-
 
472
 
-