Subversion Repositories programming

Rev

Rev 87 | Details | Compare with Previous | 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
87 irasnyd 40
 *           -- comes from quicksort() (but is not used here) */
86 irasnyd 41
int partition (int array[], unsigned long left, unsigned long right);
42
 
43
/* ---------- BEGIN QUICKSORT ---------- */
44
 
45
/* compare function for stdlib's qsort() */
46
int cmp_func (const void* _a, const void* _b)
47
{
48
    const int* a = (const int*) _a;
49
    const int* b = (const int*) _b;
50
 
51
    if (*a > *b)
52
        return 1;
53
    else if (*a == *b)
54
        return 0;
55
    else
56
        return -1;
57
}
58
 
59
/* wrapper for stdlib's qsort() */
60
void quicksort (int array[], unsigned long size)
61
{
62
    qsort ((void*)array, size, sizeof(int), cmp_func);
63
}
64
 
65
/* ---------- END QUICKSORT ---------- */
66
 
67
/* ---------- BEGIN MERGESORT ---------- */
68
 
69
/* Mergesort an array
70
 * Sets up the correct parameters and hands off the work to
71
 * mergesort_rec()
72
 * 
87 irasnyd 73
 * Complexity: O(n*lgn) */
86 irasnyd 74
void mergesort (int array[], unsigned long size)
75
{
76
    mergesort_rec (array, 0, size-1);
77
}
78
 
79
/* The actual mergesort call */
80
void mergesort_rec (int A[], unsigned long min, unsigned long max)
81
{
82
    unsigned long mid = (min+max)/2;
83
    unsigned long lowerCount = mid - min + 1;
84
    unsigned long upperCount = max - mid;
85
 
86
    if (max == min)
87
        return;
88
 
89
    mergesort_rec (A, min, mid);
90
    mergesort_rec (A, mid+1, max);
91
    merge (A+min, lowerCount, A+mid+1, upperCount);
92
}
93
 
94
/* merge two arrays together
95
 *
87 irasnyd 96
 * Complexity: O(n) */
86 irasnyd 97
void merge(int A[], unsigned long asize, int B[], unsigned long bsize)
98
{
99
    unsigned long ai, bi, ci, i;
100
    int *C;
101
    unsigned long csize = asize+bsize;
102
 
103
    C = create_array (csize);
104
 
105
    ai = 0;
106
    bi = 0;
107
    ci = 0;
108
 
109
    while ((ai < asize) && (bi < bsize)) 
110
    {
111
        if (A[ai] <= B[bi])
112
        {
113
            C[ci] = A[ai];
114
            ci++; ai++;
115
        }
116
        else
117
        {
118
            C[ci] = B[bi];
119
            ci++; bi++;
120
        }
121
    }
122
 
123
    if (ai >= asize)
124
        for (i = ci; i < csize; i++, bi++)
125
            C[i] = B[bi];
126
        else if (bi >= bsize)
127
            for (i = ci; i < csize; i++, ai++)
128
                C[i] = A[ai];
129
 
130
        for (i = 0; i < csize; i++)
131
            A[i] = C[i];
132
 
133
    C = free_array (C);
134
}
135
 
136
/* ---------- END MERGESORT ---------- */
137
 
138
/* ---------- BEGIN INSERTION SORT ---------- */
139
 
140
void insertsort (int array[], unsigned long size)
141
{
142
    int i, j, v;
143
 
144
    for (i=1; i<size; i++)
145
    {
146
        v = array[i];
147
        j = i;
148
 
149
        while (array[j-1] > v)
150
        {
151
            array[j] = array[j-1];
152
            j--;
153
 
154
            if (j <= 0)
155
                break;
156
        }
157
 
158
        array[j] = v;
159
    }
160
}
161
 
162
/* ---------- END INSERTION SORT ---------- */
163
 
164
/* ---------- BEGIN SELCTION SORT ---------- */
165
 
166
void selectsort(int array[], unsigned long size)
167
{
168
    int i, j, min;
169
 
170
    for (i=0; i<size-1; i++)
171
    {
172
        min = i;
173
        for (j=i+1; j<size; j++)
174
            if (array[j] < array[min])
175
                min = j;
176
 
177
        swap (&array[i], &array[min]);
178
    }
179
}
180
 
181
/* ---------- END SELECTION SORT ---------- */
182
 
183
/* ---------- BEGIN GENERIC SWAP ---------- */
184
 
185
/* swap two values */
186
void swap (int *left, int *right)
187
{
188
    int temp;
189
    temp = *left;
190
    *left = *right;
191
    *right = temp;
192
}
193
 
194
/* ---------- END GENERIC SWAP ---------- */
195
 
196
/* ---------- BEGIN PARTITION ---------- */
197
 
198
/* partition from quicksort
199
 * this partitions an array around the pivot value,
200
 * which is found in array[left].
201
 *
202
 * All values less than the pivot are on the left
203
 * All values more than the pivot are on the right
204
 *
87 irasnyd 205
 * Complexity: O(n) */
86 irasnyd 206
int partition (int array[], unsigned long left, unsigned long right)
207
{
208
    unsigned long i, last, pivot;
209
 
210
    pivot = array[left];
211
    last = left;
212
 
213
    for (i=left+1; i<=right; i++)
214
        if (array[i] < pivot)
215
        {
216
           last++;
217
           swap (&array[last], &array[i]);
218
        }
219
 
220
    swap (&array[left], &array[last]);
221
    return last;
222
}
223
 
224
/* ---------- END PARTITION ---------- */
225
 
226
#endif