home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
gdead.berkeley.edu
/
gdead.berkeley.edu.tar
/
gdead.berkeley.edu
/
pub
/
cad-tools
/
ciftomann.tar
/
sort_dir
/
fmerge.c
< prev
next >
Wrap
C/C++ Source or Header
|
1988-01-28
|
2KB
|
125 lines
#include "sort.h"
#include "sort_thing.h"
#include <stdio.h>
#define OK 1
#define READ_ITEM(i)\
( fread( &value[i].item, sizeof(thing), 1, value[i].desc )\
!= 0 ? OK : EOF )
#define FILE_INDEX(ptr) (((ptr) - value))
typedef struct {
FILE *desc;
thing item;
} value_type;
value_type value[MAX_FILES + 1];
value_type *heap[MAX_FILES + 1];
int ourcomparer();
FILE *open_file();
extern FILE *outfile_desc;
/*
* merge the files start through end into one single file using
* a heap sort to do the merging
*/
merge(start,end)
int start,end;
{
int index,num_files;
value_type *top;
num_files = 1;
for(index = start; index <= end; index++) {
value[num_files].desc = open_file(index);
heap[num_files] = &value[num_files];
if ( READ_ITEM(num_files) == OK ) {
num_files++;
}
}
num_files--;
qsort((char *) &(heap[1]),num_files,sizeof(thing *),ourcomparer);
while (num_files > 0) {
top = heap[1];
index = FILE_INDEX(top);
fwrite(&(top->item), sizeof(thing), 1, outfile_desc);
if ( READ_ITEM( index ) == EOF) {
heap[1] = heap[num_files];
num_files--;
}
reheap(num_files);
}
remove_files(start,end);
}
value_type *temp;
#define EXCHANGE(a,b) {temp = (a); (a) = (b); (b) = temp;}
/*
* reorder the heap after the insertion of a new element at
* the top
*/
reheap(num_files)
int num_files;
{
int current,child;
current = 1;
child = 2;
while ( child <= num_files ) {
if (child+1 <= num_files) {
if (comparer(&heap[child]->item,&heap[child+1]->item) > 0) {
child++;
}
}
if (comparer(&heap[current]->item,&heap[child]->item) <= 0) {
break;
}
EXCHANGE(heap[child],heap[current]);
current = child;
child = 2*current;
}
}
ourcomparer(aptr_ptr,bptr_ptr)
value_type **aptr_ptr,**bptr_ptr;
{
return(comparer(&(*aptr_ptr)->item,&(*bptr_ptr)->item));
}
remove_files(first,last)
int first,last;
{
int index;
for (index = first; index <= last; index++) {
remove_file(index);
fclose(value[index - first + 1].desc);
}
}