Subversion Repositories programming

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
86 irasnyd 1
/* sorts.c - A holder for some common sorts
2
 *
3
 * Written By: Ira Snyder
4
 * Started On: 06-02-2005
5
 * 
6
 * License: MIT License
7
 * License: http://www.opensource.org/licenses/mit-license.php
8
 *
9
 * These are all tested and work as long as you give them correct
10
 * values. DO NOT try giving them a size larger than the array, for example.
11
 */
12
 
13
#ifndef SORTS_C
14
#define SORTS_C
15
 
16
#include <stdlib.h> /* for qsort() */
17
 
18
/* include some common functions for dealing with arrays */
19
#include "arrays.c"
20
 
21
/* ---------- FUNCTION PROTOTYPES ---------- */
22
 
23
/* quicksort -- O(n*logn) best, average. O(n^2) worst */
24
int cmp_func (const void* _a, const void* _b);
25
void quicksort (int array[], unsigned long size);
26
 
27
/* mergesort -- O(n*logn) best, average, worst */
28
void mergesort (int array[], unsigned long size);
29
void mergesort_rec (int A[], unsigned long min, unsigned long max);
30
void merge (int A[], unsigned long asize, int B[], unsigned long bsize);
31
 
32
/* insertsort & selectsort -- O(n^2) sorts */
33
void insertsort (int array[], unsigned long size);
34
void selectsort(int array[], unsigned long size);
35
 
36
/* swap -- O(1) */
37
void swap (int *left, int *right);
38
 
39
/* partition -- O(n) way to move an array around a pivot
40
 *           -- comes from quicksort() (but is not used here)
41
 */
42
int partition (int array[], unsigned long left, unsigned long right);
43
 
44
/* ---------- BEGIN QUICKSORT ---------- */
45
 
46
/* compare function for stdlib's qsort() */
47
int cmp_func (const void* _a, const void* _b)
48
{
49
    const int* a = (const int*) _a;
50
    const int* b = (const int*) _b;
51
 
52
    if (*a > *b)
53
        return 1;
54
    else if (*a == *b)
55
        return 0;
56
    else
57
        return -1;
58
}
59
 
60
/* wrapper for stdlib's qsort() */
61
void quicksort (int array[], unsigned long size)
62
{
63
    qsort ((void*)array, size, sizeof(int), cmp_func);
64
}
65
 
66
/* ---------- END QUICKSORT ---------- */
67
 
68
/* ---------- BEGIN MERGESORT ---------- */
69
 
70
/* Mergesort an array
71
 * Sets up the correct parameters and hands off the work to
72
 * mergesort_rec()
73
 * 
74
 * Complexity: O(n*lgn)
75
 */
76
void mergesort (int array[], unsigned long size)
77
{
78
    mergesort_rec (array, 0, size-1);
79
}
80
 
81
/* The actual mergesort call */
82
void mergesort_rec (int A[], unsigned long min, unsigned long max)
83
{
84
    unsigned long mid = (min+max)/2;
85
    unsigned long lowerCount = mid - min + 1;
86
    unsigned long upperCount = max - mid;
87
 
88
    if (max == min)
89
        return;
90
 
91
    mergesort_rec (A, min, mid);
92
    mergesort_rec (A, mid+1, max);
93
    merge (A+min, lowerCount, A+mid+1, upperCount);
94
}
95
 
96
/* merge two arrays together
97
 *
98
 * Complexity: O(n)
99
 */
100
void merge(int A[], unsigned long asize, int B[], unsigned long bsize)
101
{
102
    unsigned long ai, bi, ci, i;
103
    int *C;
104
    unsigned long csize = asize+bsize;
105
 
106
    C = create_array (csize);
107
 
108
    ai = 0;
109
    bi = 0;
110
    ci = 0;
111
 
112
    while ((ai < asize) && (bi < bsize)) 
113
    {
114
        if (A[ai] <= B[bi])
115
        {
116
            C[ci] = A[ai];
117
            ci++; ai++;
118
        }
119
        else
120
        {
121
            C[ci] = B[bi];
122
            ci++; bi++;
123
        }
124
    }
125
 
126
    if (ai >= asize)
127
        for (i = ci; i < csize; i++, bi++)
128
            C[i] = B[bi];
129
        else if (bi >= bsize)
130
            for (i = ci; i < csize; i++, ai++)
131
                C[i] = A[ai];
132
 
133
        for (i = 0; i < csize; i++)
134
            A[i] = C[i];
135
 
136
    C = free_array (C);
137
}
138
 
139
/* ---------- END MERGESORT ---------- */
140
 
141
/* ---------- BEGIN INSERTION SORT ---------- */
142
 
143
void insertsort (int array[], unsigned long size)
144
{
145
    int i, j, v;
146
 
147
    for (i=1; i<size; i++)
148
    {
149
        v = array[i];
150
        j = i;
151
 
152
        while (array[j-1] > v)
153
        {
154
            array[j] = array[j-1];
155
            j--;
156
 
157
            if (j <= 0)
158
                break;
159
        }
160
 
161
        array[j] = v;
162
    }
163
}
164
 
165
/* ---------- END INSERTION SORT ---------- */
166
 
167
/* ---------- BEGIN SELCTION SORT ---------- */
168
 
169
void selectsort(int array[], unsigned long size)
170
{
171
    int i, j, min;
172
 
173
    for (i=0; i<size-1; i++)
174
    {
175
        min = i;
176
        for (j=i+1; j<size; j++)
177
            if (array[j] < array[min])
178
                min = j;
179
 
180
        swap (&array[i], &array[min]);
181
    }
182
}
183
 
184
/* ---------- END SELECTION SORT ---------- */
185
 
186
/* ---------- BEGIN GENERIC SWAP ---------- */
187
 
188
/* swap two values */
189
void swap (int *left, int *right)
190
{
191
    int temp;
192
    temp = *left;
193
    *left = *right;
194
    *right = temp;
195
}
196
 
197
/* ---------- END GENERIC SWAP ---------- */
198
 
199
/* ---------- BEGIN PARTITION ---------- */
200
 
201
/* partition from quicksort
202
 * this partitions an array around the pivot value,
203
 * which is found in array[left].
204
 *
205
 * All values less than the pivot are on the left
206
 * All values more than the pivot are on the right
207
 *
208
 * Complexity: O(n)
209
 */
210
int partition (int array[], unsigned long left, unsigned long right)
211
{
212
    unsigned long i, last, pivot;
213
 
214
    pivot = array[left];
215
    last = left;
216
 
217
    for (i=left+1; i<=right; i++)
218
        if (array[i] < pivot)
219
        {
220
           last++;
221
           swap (&array[last], &array[i]);
222
        }
223
 
224
    swap (&array[left], &array[last]);
225
    return last;
226
}
227
 
228
/* ---------- END PARTITION ---------- */
229
 
230
#endif