source: pcp/src/mergesort2.c@ fdbf0c

Last change on this file since fdbf0c was 79290f, checked in by Frederik Heber <heber@…>, 17 years ago

config.h is included in each and every file. After trying to compile on JUMP (with xlc).

  • Property mode set to 100644
File size: 4.3 KB
Line 
1/** \file mergesort2.c
2 * MergeSort implementation.
3 * Unbeknownst that C already chooses the best algorithim according to the
4 * problem at hand, a mergesort algorithm was implemented by naturalmergesort(),
5 * which does the sorting, and merge() which joins two sorted pieces in an array
6 * together.
7 *
8 Project: CP
9 \author Jan Hamaekers
10 \date 2000
11
12 $Id: mergesort2.c,v 1.10 2006/12/05 18:11:16 foo Exp $
13
14 File: mergesort2.c
15 Usage:
16 Insert in your Code
17 \verbatim
18 #include"mergesort2.h"
19 double GetKey(void *Element, int i) { }
20 void CopyElement(void *Element, int i, void *Element, int j)
21 \endverbatim
22 Use:
23 naturalmergesort(a,b,l,r,&GetKey,&CopyElement)
24 struct Element* a, *b b als Puffer Speicher reservieren !!!
25 int l,r
26
27*/
28
29#ifdef HAVE_CONFIG_H
30#include <config.h>
31#endif
32
33#include<stdlib.h>
34#include "mergesort2.h"
35
36/** Merge two sorted sequences a[l]-a[m] and a[m+1]-a[r] -> a[l]-a[r].
37 * Goes in both sequences through all elements, at every one step comparing the two by GetKey
38 * and copying the lower one. Eventually, the rest of the remaining sequence is copied (into
39 * the dummyarray). And dummyarray back to original one.
40 * \param *a array containging both sequences that is to be sorted
41 * \param l start of first sequence
42 * \param m end of first sequence, also one before start of second sequence
43 * \param r end of second sequence
44 * \param *b dummyarray (used for copying hither and thither, size b = r-l+1)
45 * \param (*GetKey)(void *, int i, void *) pointer to function that decides whether a[i] is "bigger" than a[j]
46 * \param *Args additional arguments for *GetKey function, passed to it on calling
47 * \param (*CopyElement)(void *, int i, void *, int j) pointer to function, copying element b[j] to a[i]
48 */
49static void merge(void *a, int l, int m, int r, void *b, double (*GetKey)(void *, int i, void *), void *Args, void (*CopyElement)(void *, int i, void *, int j)) {
50 int h,i=l,j=m+1,k=l; // i,j start at their respective sequences
51 while (i <= m && j <= r) { // elements are copied from both parts (a[l..m] and a[m+1..r]) in order into dummyarray b[l..r]
52 if (GetKey(a,i,Args) <= GetKey(a,j,Args)) {
53 CopyElement(b, k, a, i);
54 i++;
55 } else {
56 CopyElement(b, k, a, j);
57 j++;
58 }
59 k++;
60 }
61 if (i > m) { // if in one of the sequences there yet remain some elements, copy them (simple for loop)
62 for (h=j; h <=r;h++) CopyElement(b, k+h-j, a, h);
63 } else {
64 for (h=i; h <=m;h++) CopyElement(b, k+h-i, a, h);
65 } // finally copy elements back to a
66 for (h=l; h <= r; h++) CopyElement(a, h, b, h);
67}
68
69/** Mergesort an array /a a[l,-,r].
70 * By a divide-and-conquer strategy an array is sorted: Seek first ordered sequence, mark, seek
71 * from thereon second order sequence, mark, merge these, until end and then begin again until
72 * sorted. Note, that thus already present ordered partial sequences are looked for and used.
73 * \param *a array to be sorted
74 * \param l start of to-be-sorted sequence in /a a
75 * \param r end of to-be-sorted sequence in /a a
76 * \param *b dummyarray (size b = r-l+1)
77 * \param (*GetKey)(void *, int i, void *) pointer to function that decides whether a[i] is "bigger" than a[j]
78 * \param *Args additional arguments for *GetKey function, passed to it on calling
79 * \param (*CopyElement)(void *, int i, void *, int j) pointer to function, copying element b[j] to a[i]
80 * \note Should be replaced by C's own qsort-routine, that's always optimal.
81 * \sa merge()
82 */
83void naturalmergesort(void *a, void *b, int l, int r, double (*GetKey)(void *, int i, void *), void *Args, void (*CopyElement)(void *, int i, void *, int j)) {
84/* C_min = O(N)
85 C_max = O(N)
86 */
87 int ll=0, mm=0, rr=0;
88 do {
89 rr = l-1;
90 while (rr < r) {
91 ll = rr+1;
92 mm = ll;
93 while (mm < r && GetKey(a, mm+1, Args) >= GetKey(a, mm, Args)) mm++; // mm is increased until a lower element is found
94 if (mm < r) { // was whole sequence in order already?
95 rr = mm+1; // mm
96 while (rr<r && GetKey(a, rr+1, Args) >= GetKey(a, rr, Args)) rr++; // from mm on rr is increased until a lower element is found
97 merge(a,ll,mm,rr,b,GetKey,Args,CopyElement); // merge these two ordered sequences: a[ll..mm], a[mm+1..rr]
98 } else { // ... we are finished!
99 rr = mm;
100 }
101 }
102 } while (ll != l);
103}
Note: See TracBrowser for help on using the repository browser.