Subversion Repositories programming

Rev

Rev 101 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
77 irasnyd 1
/* Written by: Ira Snyder
2
 * Started on: 05-20-2005
82 irasnyd 3
 * Due Date: 06-10-2005
77 irasnyd 4
 * CS331 Project #2
5
 */
6
 
86 irasnyd 7
 
8
/* standard headers */
77 irasnyd 9
#include <stdio.h>
10
#include <stdlib.h>
11
#include <time.h>
12
 
86 irasnyd 13
/* broken-out code for common things */
14
#include "sorts.c"
15
#include "timing.c"
16
#include "arrays.c"
17
 
18
 
19
/* function prototypes */
77 irasnyd 20
void randomfill (int array[], unsigned long size);
21
int kth_smallest_method1 (int src_array[], unsigned long size, unsigned long position);
22
int kth_smallest_method2 (int src_array[], unsigned long size, unsigned long position);
83 irasnyd 23
int kth_smallest_method3 (int src_array[], unsigned long size, unsigned long position);
24
int kth_smallest_method4 (int src_array[], unsigned long size, unsigned long position);
77 irasnyd 25
 
26
 
27
int main (void)
28
{
29
    /* create new random seed */
30
    srand((unsigned)time(NULL));
31
 
32
    unsigned long size, kth_pos;
86 irasnyd 33
    int *array;
88 irasnyd 34
    int stop_looping, i;
77 irasnyd 35
 
88 irasnyd 36
    size = 10; /* set initial size to 10 */
37
    stop_looping = 0; /* FALSE */
38
 
39
    while ( !stop_looping )
77 irasnyd 40
    {
88 irasnyd 41
        /* create and fill an array with random values */
83 irasnyd 42
        array = create_array (size);
77 irasnyd 43
        randomfill (array, size);
44
 
45
        for (i=0; i<5; i++)
46
        {
88 irasnyd 47
            /* choose the kth position based on the handout */
77 irasnyd 48
            if (i==0)
49
                kth_pos=0;
50
            else if (i==1)
51
                kth_pos=size/4;
52
            else if (i==2)
53
                kth_pos=size/2;
54
            else if (i==3)
55
                kth_pos=3*size/4;
56
            else
57
                kth_pos=size-1;
86 irasnyd 58
 
77 irasnyd 59
            /* header */
82 irasnyd 60
            printf ("Running with size=%lu (%.3fMB) kth_pos=%lu...\n",
77 irasnyd 61
                    size, (size*4.0)/(1024*1024), kth_pos);
62
 
63
            /* run method1 */
64
            startclock();
82 irasnyd 65
            printf ("%luth smallest (method1): %d -- ", kth_pos, 
77 irasnyd 66
                    kth_smallest_method1 (array, size, kth_pos));
67
            stopclock();
68
            printtimetaken("Method1");
69
 
70
            /* run method2 */
71
            startclock();
82 irasnyd 72
            printf ("%luth smallest (method2): %d -- ", kth_pos, 
77 irasnyd 73
                    kth_smallest_method2 (array, size, kth_pos));
74
            stopclock();
75
            printtimetaken("Method2");
76
 
82 irasnyd 77
            /* run method3 */
78
            startclock();
79
            printf ("%luth smallest (method3): %d -- ", kth_pos, 
80
                    kth_smallest_method3 (array, size, kth_pos));
81
            stopclock();
82
            printtimetaken("Method3");
83 irasnyd 83
 
84
            /* run method4 */
85
            startclock();
86
            printf ("%luth smallest (method4): %d -- ", kth_pos, 
87
                    kth_smallest_method4 (array, size, kth_pos));
88
            stopclock();
89
            printtimetaken("Method4");
90
 
87 irasnyd 91
            /* some blank lines for spacing */
77 irasnyd 92
            printf ("\n\n");
93
        }
94
 
88 irasnyd 95
        /* free the memory that was allocated for the array */
86 irasnyd 96
        array = free_array (array);
88 irasnyd 97
 
98
        /* choose size according to the Project #2 handout */
99
        if (size < 10)
100
            size = 10;
101
        else if (size < 50)
102
            size = 50;
103
        else if (size < 100)
104
            size = 100;
105
        else if (size < 250)
106
            size = 250;
107
        else
108
            size *= 2;
77 irasnyd 109
 
103 irasnyd 110
        /* if we grow above 262.5 million elements (about 1GB), stop looping */
111
        if (size > 262500000)
88 irasnyd 112
            stop_looping = 1; /* TRUE */
113
 
114
    } /* end while loop */
115
 
77 irasnyd 116
    return 0;
117
}
118
 
119
/* fill the array with random numbers in
87 irasnyd 120
 * the range 0-32767 */
77 irasnyd 121
void randomfill (int array[], unsigned long size)
122
{
123
    unsigned long i;
124
 
125
    for (i=0; i<size; i++)
126
        array[i] = rand() % 32768;
127
}
128
 
129
/* Find the kth smallest element in the array (starting from zero)
130
 *
131
 * This uses the method of sorting the list, then picking
87 irasnyd 132
 * the correct element */
82 irasnyd 133
int kth_smallest_method1 (int src_array[], unsigned long size, 
134
        unsigned long position)
77 irasnyd 135
{
136
    int *array;
137
    int retval;
138
 
83 irasnyd 139
    array = create_array (size);
77 irasnyd 140
    copyarray (src_array, array, size);
141
 
142
    mergesort (array, size);
143
 
144
    retval = array[position];
86 irasnyd 145
    array = free_array (array);
83 irasnyd 146
 
77 irasnyd 147
    return retval;
148
}
149
 
150
/* Find the kth smallest element in the array (starting from zero)
151
 *
152
 * This uses the method of calling partiton() from quicksort, and
87 irasnyd 153
 * throwing out data that is unneeded */
77 irasnyd 154
int kth_smallest_method2 (int src_array[], unsigned long size, unsigned long position)
155
{
156
    int *array;
157
    int retval;
158
    unsigned long left = 0;
159
    unsigned long right = size-1;
160
    unsigned long pivotpos;
161
 
83 irasnyd 162
    array = create_array (size);
77 irasnyd 163
    copyarray (src_array, array, size);
164
 
165
    do
166
    {
167
        swap (&array[position], &array[left]);
168
        pivotpos = partition (array, left, right);
169
 
170
        if (pivotpos < position)
171
            left = pivotpos + 1;
172
        else /* pivotpos >= position) */
82 irasnyd 173
            right = pivotpos - 1;
77 irasnyd 174
    }
175
    while (pivotpos != position);
176
 
177
    retval = array[position];
86 irasnyd 178
    array = free_array (array);
83 irasnyd 179
 
77 irasnyd 180
    return retval;
181
}
182
 
87 irasnyd 183
/* Find the kth smallest element in the array (starting from zero)
184
 *
185
 * This uses the method of calling partiton() from quicksort, and
186
 * throwing out data that is unneeded
187
 *
188
 * NOTE: This is a recursive version of the algorithm above (kth_smallest_method2) */
82 irasnyd 189
int kth_smallest_method3 (int src_array[], unsigned long size, unsigned long position)
190
{
191
    int *array;
192
    int *temparray;
193
    int retval;
194
    unsigned long left = 0;
195
    unsigned long right = size-1;
196
    unsigned long pivotpos, newpos;
197
 
83 irasnyd 198
    array = create_array (size);
82 irasnyd 199
    copyarray (src_array, array, size);
200
 
201
    swap (&array[position], &array[left]);
202
    pivotpos = partition (array, left, right);
203
 
204
    /* base case */
205
    if (pivotpos == position)
206
    {
207
        retval = array[position];
86 irasnyd 208
        array = free_array (array);
83 irasnyd 209
 
82 irasnyd 210
        return retval;
211
    }
212
 
213
    /* throw away left side */
214
    if (pivotpos < position)
215
    {
216
        left = pivotpos + 1;
217
        newpos = position - left;
218
    }
219
    else /* pivotpos >= position) */ /* throw away right side */
220
    {
221
        right = pivotpos - 1;
222
        newpos = position;
223
    }
224
 
83 irasnyd 225
    temparray = create_array (right-left+1);
226
    copyarray_partial (array, temparray, left, right);
227
 
228
    retval = kth_smallest_method3 (temparray, right-left+1, newpos);
229
 
86 irasnyd 230
    temparray = free_array (temparray);
231
    array = free_array (array);
83 irasnyd 232
 
233
    return retval;
234
}
235
 
87 irasnyd 236
/* Find the kth smallest element in the array (starting from zero)
237
 * 
238
 * This method uses both partition() from quicksort, as well as using
239
 * the "median of medians" rule to throw away as much data as possible */
83 irasnyd 240
int kth_smallest_method4 (int src_array[], unsigned long size, unsigned long position)
241
{
242
    int *array;
243
    int *medianarray;
244
    int *temparray = NULL;
87 irasnyd 245
    int group_size = 11; /* choose any odd number, 11 works well in my tests */
83 irasnyd 246
    int i, left=0, right=group_size-1;
247
    int num_groups = size/group_size;
248
    int retval;
249
    int pivotpos;
250
 
251
    array = create_array (size);
252
    copyarray (src_array, array, size);
253
 
254
    /* base case */
255
    if (size <= group_size)
82 irasnyd 256
    {
86 irasnyd 257
        insertsort (array, size);
83 irasnyd 258
        retval = array[position];
259
 
86 irasnyd 260
        array = free_array (array);
83 irasnyd 261
 
262
        return retval;
82 irasnyd 263
    }
83 irasnyd 264
 
84 irasnyd 265
    /* get the array of medians */
266
    medianarray = create_array (num_groups);
267
    temparray = create_array (group_size);
268
 
83 irasnyd 269
    for (i=0; i<num_groups; i++)
270
    {
84 irasnyd 271
        copyarray_partial (array, temparray, left, right);
86 irasnyd 272
        insertsort (temparray, group_size);
84 irasnyd 273
        medianarray[i] = temparray[group_size/2];
83 irasnyd 274
        left = right + 1;
275
        right = left + group_size - 1;
276
    }
82 irasnyd 277
 
86 irasnyd 278
    temparray = free_array (temparray);
84 irasnyd 279
 
83 irasnyd 280
    /* find the median of medians */
281
    retval = kth_smallest_method4 (medianarray, num_groups, num_groups/2);
282
 
283
    /* move the mm to the 0th position in the array (for partition) */
284
    for (i=0; i<size; i++)
285
    {
286
        if (array[i] == retval)
287
        {
288
            swap (&array[i], &array[0]);
289
            break;
290
        }
291
    }
292
 
293
    /* find pivotpos using partition() */
294
    pivotpos = partition (array, 0, size-1);
295
 
296
    if (position == pivotpos)
85 irasnyd 297
    { /* no-op */ }
83 irasnyd 298
    else if (position < pivotpos)
299
    {
300
        temparray = create_array (pivotpos);
301
        copyarray_partial (array, temparray, 0, pivotpos-1);
302
        retval = kth_smallest_method4 (temparray, pivotpos, position);
303
    }
304
    else
305
    {
306
        temparray = create_array (size-(pivotpos+1));
307
        copyarray_partial (array, temparray, pivotpos+1, size-1);
308
        retval = kth_smallest_method4 (temparray, size-(pivotpos+1), position-(pivotpos+1));
309
    }
82 irasnyd 310
 
86 irasnyd 311
    array = free_array (array);
312
    medianarray = free_array (medianarray);
83 irasnyd 313
    if (temparray != NULL)
314
    {
86 irasnyd 315
        temparray = free_array (temparray);
83 irasnyd 316
    }
317
 
82 irasnyd 318
    return retval;
319
}
320