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
3
 * Due Date: 06-01-2005
4
 * CS331 Project #2
5
 *
6
 * Changelog Follows:
7
 *
8
 */
9
 
10
#include <stdio.h>
11
#include <stdlib.h>
12
#include <time.h>
13
 
14
void mergesort (int array[], unsigned long size);
15
void mergesort_rec (int A[], unsigned long min, unsigned long max);
16
void merge (int A[], unsigned long asize, int B[], unsigned long bsize);
17
void swap (int *left, int *right);
18
void printarray (int array[], unsigned long size);
19
void randomfill (int array[], unsigned long size);
20
int partition (int array[], unsigned long left, unsigned long right);
21
void copyarray (int src[], int dst[], unsigned long size);
22
int kth_smallest_method1 (int src_array[], unsigned long size, unsigned long position);
23
int kth_smallest_method2 (int src_array[], unsigned long size, unsigned long position);
24
 
25
void startclock (void);
26
void stopclock (void);
27
void printtimetaken (char *funcname);
28
 
29
 
30
/* global timeval for timing the function calls */
31
struct timeval start_time, end_time, lapsed;
32
 
33
int main (void)
34
{
35
    /* create new random seed */
36
    srand((unsigned)time(NULL));
37
 
38
    unsigned long size, kth_pos;
39
    int* array;
40
    int i;
41
 
42
    for (size=50; size<=3000; size+=50)
43
    {
44
        if ( (array = (int*) malloc (size*sizeof(int))) == NULL)
45
        {
46
            printf ("Ran out of memory at size=%d\n", size);
47
            exit(1);
48
        }
49
 
50
        /* fill the array with random values */
51
        randomfill (array, size);
52
 
53
        for (i=0; i<5; i++)
54
        {
55
            if (i==0)
56
                kth_pos=0;
57
            else if (i==1)
58
                kth_pos=size/4;
59
            else if (i==2)
60
                kth_pos=size/2;
61
            else if (i==3)
62
                kth_pos=3*size/4;
63
            else
64
                kth_pos=size-1;
65
            /* header */
66
            printf ("Running with size=%d (%.3fMB) kth_pos=%d...\n", 
67
                    size, (size*4.0)/(1024*1024), kth_pos);
68
 
69
            /* run method1 */
70
            startclock();
71
            printf ("%dth smallest (method1): %d -- ", kth_pos, 
72
                    kth_smallest_method1 (array, size, kth_pos));
73
            stopclock();
74
            printtimetaken("Method1");
75
 
76
            /* run method2 */
77
            startclock();
78
            printf ("%dth smallest (method2): %d -- ", kth_pos, 
79
                    kth_smallest_method2 (array, size, kth_pos));
80
            stopclock();
81
            printtimetaken("Method2");
82
 
83
            printf ("\n\n");
84
        }
85
 
86
        free (array);
87
        array = NULL;
88
    }
89
 
90
    return 0;
91
}
92
 
93
/* Mergesort an array
94
 * Sets up the correct parameters and hands off the work to
95
 * mergesort_rec()
96
 * 
97
 * Complexity: O(n*lgn)
98
 */
99
void mergesort (int array[], unsigned long size)
100
{
101
    mergesort_rec (array, 0, size-1);
102
}
103
 
104
/* The actual mergesort call */
105
void mergesort_rec (int A[], unsigned long min, unsigned long max)
106
{
107
    unsigned long mid = (min+max)/2;
108
    unsigned long lowerCount = mid - min + 1;
109
    unsigned long upperCount = max - mid;
110
 
111
    if (max == min)
112
        return;
113
 
114
    mergesort_rec (A, min, mid);
115
    mergesort_rec (A, mid+1, max);
116
    merge (A+min, lowerCount, A+mid+1, upperCount);
117
}
118
 
119
/* merge two arrays together
120
 *
121
 * Complexity: O(n)
122
 */
123
void merge(int A[], unsigned long asize, int B[], unsigned long bsize)
124
{
125
    unsigned long ai, bi, ci, i;
126
    int *C;
127
    unsigned long csize = asize+bsize;
128
 
129
    C = (int*) malloc (csize * sizeof(int));
130
 
131
    if (C == NULL)
132
    {
133
        printf("Out of memory... Exiting\n");
134
        exit(1);
135
    }
136
 
137
    ai = 0;
138
    bi = 0;
139
    ci = 0;
140
 
141
    while ((ai < asize) && (bi < bsize)) 
142
    {
143
        if (A[ai] <= B[bi])
144
        {
145
            C[ci] = A[ai];
146
            ci++; ai++;
147
        }
148
        else
149
        {
150
            C[ci] = B[bi];
151
            ci++; bi++;
152
        }
153
    }
154
 
155
    if (ai >= asize)
156
        for (i = ci; i < csize; i++, bi++)
157
            C[i] = B[bi];
158
        else if (bi >= bsize)
159
            for (i = ci; i < csize; i++, ai++)
160
                C[i] = A[ai];
161
 
162
        for (i = 0; i < csize; i++)
163
            A[i] = C[i];
164
 
165
    free (C);
166
}
167
 
168
/* swap two values */
169
void swap (int *left, int *right)
170
{
171
    int temp;
172
    temp = *left;
173
    *left = *right;
174
    *right = temp;
175
}
176
 
177
/* print out the contents of the array
178
 * used for debugging mainly
179
 */
180
void printarray (int array[], unsigned long size)
181
{
182
    unsigned long i;
183
 
184
    printf("Printing %d elements\n", size);
185
 
186
    for (i=0; i<size; i++)
187
        printf("%d ", array[i]);
188
 
189
    printf("\n");
190
}
191
 
192
/* fill the array with random numbers in
193
 * the range 0-32767
194
 */
195
void randomfill (int array[], unsigned long size)
196
{
197
    unsigned long i;
198
 
199
    for (i=0; i<size; i++)
200
        array[i] = rand() % 32768;
201
}
202
 
203
/* partition from quicksort
204
 * this partitions an array around the pivot value,
205
 * which is found in array[left].
206
 *
207
 * All values less than the pivot are on the left
208
 * All values more than the pivot are on the right
209
 *
210
 * Complexity: O(n)
211
 */
212
int partition (int array[], unsigned long left, unsigned long right)
213
{
214
    unsigned long i, last, pivot;
215
 
216
    pivot = array[left];
217
    last = left;
218
 
219
    for (i=left+1; i<=right; i++)
220
        if (array[i] < pivot)
221
        {
222
           last++;
223
           swap (&array[last], &array[i]);
224
        }
225
 
226
    swap (&array[left], &array[last]);
227
    return last;
228
}
229
 
230
/* start the clock (for timing) */
231
void startclock (void)
232
{
233
    gettimeofday(&start_time, NULL);
234
}
235
 
236
/* stop the clock (for timing) */
237
void stopclock (void)
238
{
239
    gettimeofday(&end_time, NULL);
240
}
241
 
242
/* print the time taken, in milliseconds = seconds / 1000 */
243
void printtimetaken (char *funcname)
244
{
245
    double total_usecs = (end_time.tv_sec-start_time.tv_sec) * 1000000.0
246
                       + (end_time.tv_usec-start_time.tv_usec);
247
 
248
    printf("%s : %.3lf milliseconds\n", funcname, total_usecs/1000.0);
249
}
250
 
251
/* copy the src[] to dst[] */
252
void copyarray (int src[], int dst[], unsigned long size)
253
{
254
    unsigned long i;
255
 
256
    for (i=0; i<size; i++)
257
        dst[i] = src[i];
258
}
259
 
260
/* Find the kth smallest element in the array (starting from zero)
261
 *
262
 * This uses the method of sorting the list, then picking
263
 * the correct element
264
 */
265
int kth_smallest_method1 (int src_array[], unsigned long size, unsigned long position)
266
{
267
    //int array[size];
268
    int *array;
269
    int retval;
270
 
271
    if ( (array = (int*) malloc (size*sizeof(int))) == NULL)
272
    {
273
        printf ("Out of memory at size=%d\n", size);
274
        exit(1);
275
    }
276
 
277
    copyarray (src_array, array, size);
278
 
279
    mergesort (array, size);
280
 
281
    retval = array[position];
282
    free (array);
283
    array = NULL;
284
    return retval;
285
}
286
 
287
/* Find the kth smallest element in the array (starting from zero)
288
 *
289
 * This uses the method of calling partiton() from quicksort, and
290
 * throwing out data that is unneeded
291
 */
292
int kth_smallest_method2 (int src_array[], unsigned long size, unsigned long position)
293
{
294
    //int array[size];
295
    int *array;
296
    int retval;
297
    unsigned long left = 0;
298
    unsigned long right = size-1;
299
    unsigned long pivotpos;
300
 
301
    if ( (array = (int*) malloc (size*sizeof(int))) == NULL)
302
    {
303
        printf ("Out of memory at size=%d\n", size);
304
        exit(1);
305
    }
306
 
307
    copyarray (src_array, array, size);
308
 
309
    do
310
    {
311
        swap (&array[position], &array[left]);
312
        pivotpos = partition (array, left, right);
313
 
314
        if (pivotpos < position)
315
            left = pivotpos + 1;
316
        else /* pivotpos >= position) */
317
            right = pivotpos-1;
318
    }
319
    while (pivotpos != position);
320
 
321
    retval = array[position];
322
    free (array);
323
    array = NULL;
324
    return retval;
325
}
326