Reference Blog: http://www.cnblogs.com/benjamin-t/p/3325401.html
The generation of a single string is chosen by substitution algorithm.
Multi-way merge uses the loser tree.
#include <fstream> #include <iostream> #include <cstdlib> #include <cassert> #include <ctime
> Using namespace std;
#define MAX_INT 0x7fffffff #define MIN_INT-1 const INT kmaxsize = 100;
const int kmaxway = 10; int buffer[kmaxsize];
Assume that memory can only be put into 1 million integer types.
int heap_size;
int num_of_runs; int Ls[kmaxway];
Loser Tree, Ls[0] is the position of the smallest value, the rest is the position of the losers Run *runs[kmaxway];
void Swap (int* arr, int i, int j) {int tmp = Arr[i];
Arr[i] = Arr[j];
ARR[J] = tmp;
} void Siftdown (int* heap, int pos, int size)//maintenance minimum heap {while (pos < SIZE/2) {int tmp = 2 * pos + 1;
int rc = 2 * pos + 2;
if ((rc<size) && HEAP[TMP]>HEAP[RC]) tmp = RC;
if (Heap[pos] < heap[tmp]) return;
Swap (Heap, POS, TMP);
POS = tmp;
} void Buildheap (int* heap, int size) {for (int i = SIZE/2-1; I >= 0; i--) siftdown (heap, I, size); //Returns the number of generated strings int generateruns (const CHAr* in_file) {ifstream in (in_file);
ASSERT (in);
Char output_file[20];
Ofstream out;
int i = 0, count1 = 0;
int num;
while (!in.eof ()) {in >> buffer[i];
if (++i = = kmaxsize) break;
while (i = = kmaxsize) {heap_size = kmaxsize;
count1++;
Out.close ();
sprintf (output_file, "%d.txt", count1);
Out.open (output_file);
Buildheap (buffer, heap_size);
while (true) {if (in.eof ()) break;
if (heap_size = = 0) break;
Out << buffer[0] << Endl;
In >> num;
if (num > Buffer[0]) buffer[0] = num;
else {buffer[0] = buffer[heap_size-1];
BUFFER[HEAP_SIZE-1] = num;
heap_size--;
} siftdown (buffer, 0, heap_size); } if (heap_size!= 0)///input buffer is empty {i = i-heap_size;//i is a temporary variable, used to record remaining data while (heap_size!= 0) {out <
< buffer[0] << Endl;
Buffer[0] = buffer[--heap_size];
Siftdown (buffer, 0, heap_size); }}//process remaining data in buffer if (I!= 0) {Heap_size = i;
count1++;
Out.close ();
sprintf (output_file, "%d.txt", count1);
Out.open (output_file);
int offset = kmaxsize-heap_size;
Buildheap (buffer + offset, heap_size);
while (heap_size!= 0) {out << buffer[offset] << Endl;
Buffer[offset] = buffer[--heap_size + offset];
Siftdown (buffer + offset, 0, heap_size);
} out.close ();
return count1;
} void Adjust (Run **runs, int n, int s) {///first computes which subscript int t = (s + N)/2 in the corresponding LS according to S.
int tmp;
while (t!= 0) {if (s = = 1) break;
if (ls[t] = =-1 | | runs[s]->buffer[runs[s]->idx] > RUNS[LS[T]]->BUFFER[RUNS[LS[T]]->IDX]) {tmp = s;
s = ls[t];
LS[T] = tmp;
} t/= 2;
} Ls[0] = s;
} void Createlosertree (Run **rus, int n) {for (int i = 0; i < n; i++) Ls[i] =-1;
for (int i = n-1 i >= 0; i--) Adjust (runs, n, i); } void MergeSort (run** runs, int num_of_runs, const char* file_out) {//Initialize Run if (num_of_runs> kmaxway) num_of_r
uns = Kmaxway; INT Length_per_run = kmaxsize/num_of_runs;
for (int i = 0; i < num_of_runs i++) Runs[i]->buffer = buffer + I*length_per_run;
Ifstream In[kmaxway];
Char file_name[20];
for (int i = 0; i < num_of_runs i++) {sprintf (file_name, "%d.txt", i + 1);
In[i].open (file_name);
//Read the data of the string file into the buffer for (int i = 0; i < num_of_runs i++) {int j = 0;
while (In[i] >> Runs[i]->buffer[j]) {j + +;
if (j = = Length_per_run) break;
} runs[i]->length = J;
Runs[i]->idx = 0;
} createlosertree (runs, num_of_runs);
Ofstream out (file_out);
int live_runs = Num_of_runs;
while (Live_runs > 0) {out << runs[ls[0]]->buffer[runs[ls[0]]->idx++] << Endl;
if (Runs[ls[0]]->idx = = runs[ls[0]]->length) {int j = 0;
while (In[ls[0]] >> Runs[ls[0]]->buffer[j]) {j + +;
if (j = = Length_per_run) break;
} runs[ls[0]]->length = J;
Runs[ls[0]]->idx = 0; } if (Runs[ls[0]]->lenGth = = 0) {Runs[ls[0]]->buffer[runs[ls[0]]->idx] = Max_int;
live_runs--;
} Adjust (Runs, Num_of_runs, Ls[0]);
} void InitData ();
int main () {initdata ();
Char *in_file = "Data.txt";
clock_t T;
cout << "Generate Shun Series ..." << Endl;
Num_of_runs = 6;
t = Clock ();
Num_of_runs = Generateruns (in_file);
t = clock ()-t;
cout << "Shun string generation Success, Quantity:" << num_of_runs << Endl;
cout << "Time Consuming:" << (double) t/clocks_per_sec << "s" << Endl;
cout << "merge begins ..." << Endl;
t = Clock ();
for (int i = 0; i < num_of_runs i++) runs[i] = new Run ();
MergeSort (Runs, num_of_runs, "sorted");
t = clock ()-t;
cout << "merge successfully." << Endl;
cout << "Time Consuming:" << (double) t/clocks_per_sec << "s" << Endl;}
void InitData () {file* F = fopen ("Data.txt", "wt");
Srand ((unsigned) time (NULL));
for (int i = 0; i < 930 i++) fprintf (F, "%d", rand ()% 930);
Fclose (f); }