source: pcp/src/mergesort2.c@ acd467

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

-initial commit
-Minimum set of files needed from ESPACK SVN repository
-Switch to three tantamount package parts instead of all relating to pcp (as at some time Ralf's might find inclusion as well)

  • Property mode set to 100644
File size: 4.2 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#include<stdlib.h>
30#include "mergesort2.h"
31
32/** Merge two sorted sequences a[l]-a[m] and a[m+1]-a[r] -> a[l]-a[r].
33 * Goes in both sequences through all elements, at every one step comparing the two by GetKey
34 * and copying the lower one. Eventually, the rest of the remaining sequence is copied (into
35 * the dummyarray). And dummyarray back to original one.
36 * \param *a array containging both sequences that is to be sorted
37 * \param l start of first sequence
38 * \param m end of first sequence, also one before start of second sequence
39 * \param r end of second sequence
40 * \param *b dummyarray (used for copying hither and thither, size b = r-l+1)
41 * \param (*GetKey)(void *, int i, void *) pointer to function that decides whether a[i] is "bigger" than a[j]
42 * \param *Args additional arguments for *GetKey function, passed to it on calling
43 * \param (*CopyElement)(void *, int i, void *, int j) pointer to function, copying element b[j] to a[i]
44 */
45static 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)) {
46 int h,i=l,j=m+1,k=l; // i,j start at their respective sequences
47 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]
48 if (GetKey(a,i,Args) <= GetKey(a,j,Args)) {
49 CopyElement(b, k, a, i);
50 i++;
51 } else {
52 CopyElement(b, k, a, j);
53 j++;
54 }
55 k++;
56 }
57 if (i > m) { // if in one of the sequences there yet remain some elements, copy them (simple for loop)
58 for (h=j; h <=r;h++) CopyElement(b, k+h-j, a, h);
59 } else {
60 for (h=i; h <=m;h++) CopyElement(b, k+h-i, a, h);
61 } // finally copy elements back to a
62 for (h=l; h <= r; h++) CopyElement(a, h, b, h);
63}
64
65/** Mergesort an array /a a[l,-,r].
66 * By a divide-and-conquer strategy an array is sorted: Seek first ordered sequence, mark, seek
67 * from thereon second order sequence, mark, merge these, until end and then begin again until
68 * sorted. Note, that thus already present ordered partial sequences are looked for and used.
69 * \param *a array to be sorted
70 * \param l start of to-be-sorted sequence in /a a
71 * \param r end of to-be-sorted sequence in /a a
72 * \param *b dummyarray (size b = r-l+1)
73 * \param (*GetKey)(void *, int i, void *) pointer to function that decides whether a[i] is "bigger" than a[j]
74 * \param *Args additional arguments for *GetKey function, passed to it on calling
75 * \param (*CopyElement)(void *, int i, void *, int j) pointer to function, copying element b[j] to a[i]
76 * \note Should be replaced by C's own qsort-routine, that's always optimal.
77 * \sa merge()
78 */
79void 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)) {
80/* C_min = O(N)
81 C_max = O(N)
82 */
83 int ll=0, mm=0, rr=0;
84 do {
85 rr = l-1;
86 while (rr < r) {
87 ll = rr+1;
88 mm = ll;
89 while (mm < r && GetKey(a, mm+1, Args) >= GetKey(a, mm, Args)) mm++; // mm is increased until a lower element is found
90 if (mm < r) { // was whole sequence in order already?
91 rr = mm+1; // mm
92 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
93 merge(a,ll,mm,rr,b,GetKey,Args,CopyElement); // merge these two ordered sequences: a[ll..mm], a[mm+1..rr]
94 } else { // ... we are finished!
95 rr = mm;
96 }
97 }
98 } while (ll != l);
99}
Note: See TracBrowser for help on using the repository browser.