Subversion Repositories programming

Rev

Details | 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;
77 irasnyd 34
    int i;
35
 
86 irasnyd 36
    for (size=1000000; size<=2000000; size+=1000000)
77 irasnyd 37
    {
83 irasnyd 38
        array = create_array (size);
77 irasnyd 39
 
40
        /* fill the array with random values */
41
        randomfill (array, size);
42
 
43
        for (i=0; i<5; i++)
44
        {
45
            if (i==0)
46
                kth_pos=0;
47
            else if (i==1)
48
                kth_pos=size/4;
49
            else if (i==2)
50
                kth_pos=size/2;
51
            else if (i==3)
52
                kth_pos=3*size/4;
53
            else
54
                kth_pos=size-1;
86 irasnyd 55
 
77 irasnyd 56
            /* header */
82 irasnyd 57
            printf ("Running with size=%lu (%.3fMB) kth_pos=%lu...\n",
77 irasnyd 58
                    size, (size*4.0)/(1024*1024), kth_pos);
59
 
60
            /* run method1 */
61
            startclock();
82 irasnyd 62
            printf ("%luth smallest (method1): %d -- ", kth_pos, 
77 irasnyd 63
                    kth_smallest_method1 (array, size, kth_pos));
64
            stopclock();
65
            printtimetaken("Method1");
66
 
67
            /* run method2 */
68
            startclock();
82 irasnyd 69
            printf ("%luth smallest (method2): %d -- ", kth_pos, 
77 irasnyd 70
                    kth_smallest_method2 (array, size, kth_pos));
71
            stopclock();
72
            printtimetaken("Method2");
73
 
82 irasnyd 74
            /* run method3 */
75
            startclock();
76
            printf ("%luth smallest (method3): %d -- ", kth_pos, 
77
                    kth_smallest_method3 (array, size, kth_pos));
78
            stopclock();
79
            printtimetaken("Method3");
83 irasnyd 80
 
81
            /* run method4 */
82
            startclock();
83
            printf ("%luth smallest (method4): %d -- ", kth_pos, 
84
                    kth_smallest_method4 (array, size, kth_pos));
85
            stopclock();
86
            printtimetaken("Method4");
87
 
77 irasnyd 88
            printf ("\n\n");
89
        }
90
 
86 irasnyd 91
        array = free_array (array);
77 irasnyd 92
    }
93
 
94
    return 0;
95
}
96
 
97
/* fill the array with random numbers in
98
 * the range 0-32767
99
 */
100
void randomfill (int array[], unsigned long size)
101
{
102
    unsigned long i;
103
 
104
    for (i=0; i<size; i++)
105
        array[i] = rand() % 32768;
106
}
107
 
108
/* Find the kth smallest element in the array (starting from zero)
109
 *
110
 * This uses the method of sorting the list, then picking
111
 * the correct element
112
 */
82 irasnyd 113
int kth_smallest_method1 (int src_array[], unsigned long size, 
114
        unsigned long position)
77 irasnyd 115
{
116
    int *array;
117
    int retval;
118
 
83 irasnyd 119
    array = create_array (size);
77 irasnyd 120
    copyarray (src_array, array, size);
121
 
122
    mergesort (array, size);
123
 
124
    retval = array[position];
86 irasnyd 125
    array = free_array (array);
83 irasnyd 126
 
77 irasnyd 127
    return retval;
128
}
129
 
130
/* Find the kth smallest element in the array (starting from zero)
131
 *
132
 * This uses the method of calling partiton() from quicksort, and
133
 * throwing out data that is unneeded
134
 */
135
int kth_smallest_method2 (int src_array[], unsigned long size, unsigned long position)
136
{
137
    int *array;
138
    int retval;
139
    unsigned long left = 0;
140
    unsigned long right = size-1;
141
    unsigned long pivotpos;
142
 
83 irasnyd 143
    array = create_array (size);
77 irasnyd 144
    copyarray (src_array, array, size);
145
 
146
    do
147
    {
148
        swap (&array[position], &array[left]);
149
        pivotpos = partition (array, left, right);
150
 
151
        if (pivotpos < position)
152
            left = pivotpos + 1;
153
        else /* pivotpos >= position) */
82 irasnyd 154
            right = pivotpos - 1;
77 irasnyd 155
    }
156
    while (pivotpos != position);
157
 
158
    retval = array[position];
86 irasnyd 159
    array = free_array (array);
83 irasnyd 160
 
77 irasnyd 161
    return retval;
162
}
163
 
82 irasnyd 164
int kth_smallest_method3 (int src_array[], unsigned long size, unsigned long position)
165
{
166
    int *array;
167
    int *temparray;
168
    int retval;
169
    unsigned long left = 0;
170
    unsigned long right = size-1;
171
    unsigned long pivotpos, newpos;
172
 
83 irasnyd 173
    array = create_array (size);
82 irasnyd 174
    copyarray (src_array, array, size);
175
 
176
    swap (&array[position], &array[left]);
177
    pivotpos = partition (array, left, right);
178
 
179
    /* base case */
180
    if (pivotpos == position)
181
    {
182
        retval = array[position];
86 irasnyd 183
        array = free_array (array);
83 irasnyd 184
 
82 irasnyd 185
        return retval;
186
    }
187
 
188
    /* throw away left side */
189
    if (pivotpos < position)
190
    {
191
        left = pivotpos + 1;
192
        newpos = position - left;
193
    }
194
    else /* pivotpos >= position) */ /* throw away right side */
195
    {
196
        right = pivotpos - 1;
197
        newpos = position;
198
    }
199
 
83 irasnyd 200
    temparray = create_array (right-left+1);
201
    copyarray_partial (array, temparray, left, right);
202
 
203
    retval = kth_smallest_method3 (temparray, right-left+1, newpos);
204
 
86 irasnyd 205
    temparray = free_array (temparray);
206
    array = free_array (array);
83 irasnyd 207
 
208
    return retval;
209
}
210
 
211
int kth_smallest_method4 (int src_array[], unsigned long size, unsigned long position)
212
{
213
    int *array;
214
    int *medianarray;
215
    int *temparray = NULL;
85 irasnyd 216
    int group_size = 11;
83 irasnyd 217
    int i, left=0, right=group_size-1;
218
    int num_groups = size/group_size;
219
    int retval;
220
    int pivotpos;
221
 
222
    array = create_array (size);
223
    copyarray (src_array, array, size);
224
 
225
    /* base case */
226
    if (size <= group_size)
82 irasnyd 227
    {
86 irasnyd 228
        insertsort (array, size);
83 irasnyd 229
        retval = array[position];
230
 
86 irasnyd 231
        array = free_array (array);
83 irasnyd 232
 
233
        return retval;
82 irasnyd 234
    }
83 irasnyd 235
 
84 irasnyd 236
    /* get the array of medians */
237
    medianarray = create_array (num_groups);
238
    temparray = create_array (group_size);
239
 
83 irasnyd 240
    for (i=0; i<num_groups; i++)
241
    {
84 irasnyd 242
        copyarray_partial (array, temparray, left, right);
86 irasnyd 243
        insertsort (temparray, group_size);
84 irasnyd 244
        medianarray[i] = temparray[group_size/2];
83 irasnyd 245
        left = right + 1;
246
        right = left + group_size - 1;
247
    }
82 irasnyd 248
 
86 irasnyd 249
    temparray = free_array (temparray);
84 irasnyd 250
 
83 irasnyd 251
    /* find the median of medians */
252
    retval = kth_smallest_method4 (medianarray, num_groups, num_groups/2);
253
 
254
    /* move the mm to the 0th position in the array (for partition) */
255
    for (i=0; i<size; i++)
256
    {
257
        if (array[i] == retval)
258
        {
259
            swap (&array[i], &array[0]);
260
            break;
261
        }
262
    }
263
 
264
    /* find pivotpos using partition() */
265
    pivotpos = partition (array, 0, size-1);
266
 
267
    if (position == pivotpos)
85 irasnyd 268
    { /* no-op */ }
83 irasnyd 269
    else if (position < pivotpos)
270
    {
271
        temparray = create_array (pivotpos);
272
        copyarray_partial (array, temparray, 0, pivotpos-1);
273
        retval = kth_smallest_method4 (temparray, pivotpos, position);
274
    }
275
    else
276
    {
277
        temparray = create_array (size-(pivotpos+1));
278
        copyarray_partial (array, temparray, pivotpos+1, size-1);
279
        retval = kth_smallest_method4 (temparray, size-(pivotpos+1), position-(pivotpos+1));
280
    }
82 irasnyd 281
 
86 irasnyd 282
    array = free_array (array);
283
    medianarray = free_array (medianarray);
83 irasnyd 284
    if (temparray != NULL)
285
    {
86 irasnyd 286
        temparray = free_array (temparray);
83 irasnyd 287
    }
288
 
82 irasnyd 289
    return retval;
290
}
291