Free Web Hosting by Netfirms
Web Hosting by Netfirms | Free Domain Names by Netfirms

Home Page    

 

/* Bins.c
   Possible bin array for RadixSort
*/

#include <stdlib.h>
#include <stdio.h>
#include <assert.h>

#include "Bins.h"

struct t_bins {
  int n_bins, max_items;
  int *bin_cnt;
  TYPE **bin_pts;
  };

/* Construct an array of n_bins bins,
   each with items_per_bin spaces */
Bins ConsBins( int n_bins, int items_per_bin ) {
  Bins b;
  int i;
#ifdef ONE_LARGE
  int max;
  TYPE *bins;
#endif
/* fprintf(stdout, "ConsBins %d/%d ", n_bins, items_per_bin ); fflush( stdout ); */
  b = (Bins)malloc( sizeof( struct t_bins ) );
  if ( b != NULL ) {
    b->n_bins = n_bins;
    b->max_items = items_per_bin;
    b->bin_pts = (TYPE **)malloc( n_bins*sizeof(TYPE *) );
    b->bin_cnt = (int *)calloc( n_bins, sizeof(int) );
    if ( b->bin_pts != NULL ) {
#ifdef ONE_LARGE
      /* Allocate a single large bin */
      max = n_bins*items_per_bin*sizeof(TYPE);
      bins = malloc( max );
      if( bins == NULL ) {
        printf("ConsBins: insuff mem %d bytes needed\n", max );
        return NULL;
        }
      /* Divide it into n_bins, each holding items_per_bin items */
      for(i=0;i<n_bins;i++) {
        b->bin_pts[i] = bins;
        bins += (items_per_bin);
        }
#else
      /* Allocate n_bins individual bins */
      for(i=0;i<n_bins;i++) {
        b->bin_pts[i] = (TYPE *)malloc( items_per_bin*sizeof(TYPE) );
        if( b->bin_pts[i] == NULL ) {
          printf("ConsBins: insuff mem after %d bins\n", i );
          b = NULL; break;
        }
      }
#endif
    }
  }
  else {
    fprintf( stdout, "Insuff mem\n");
  }
  return b;
  }

int AddItem( Bins b, TYPE item, int bin_index ) {
/* Add item to bin bin_index
   Pre: b != NULL && item != NULL &&
        bin_index >= 0 && bin_index < n_bins
*/
  int k;
  assert( b != NULL );
  assert( bin_index >= 0 );
  assert( bin_index < b->n_bins );
  k = b->bin_cnt[bin_index];
  assert( (k>=0) && (k<b->max_items) );
  assert( (b->bin_pts[bin_index]) != NULL );
  (b->bin_pts[bin_index])[k] = item;
  b->bin_cnt[bin_index]++;
  return 1;
  }

TYPE *MergeBins( Bins b, TYPE *list ) {
/* Merge the bins by copying all the elements in bins 1..n_bins-1
   into list
   return a pointer to list
   (This pointer can be used in the next phase!)
*/
  int j, k;
  TYPE *lp;
  assert( b != NULL );
  assert( list != NULL );

  lp = list;
  for( j = 0; j<b->n_bins; j++ ) {
    for(k=0;k<b->bin_cnt[j];k++) {
      *lp++ = (b->bin_pts[j])[k];
      }
    }
  return list;
  }

void FreeUnusedBins( Bins b  ) {
/* Free bins 1 .. n_bins-1 in preparation for next phase */
  int k;
  assert( b != NULL );
#ifdef ONE_LARGE
  free( b->bin_pts[0] );
#else
  for(k=0;k<b->n_bins;k++) {
    assert( b->bin_pts[k] != NULL );
    free( b->bin_pts[k] );
    }
#endif
  free( b->bin_pts );
  }

void DeleteBins( Bins b ) {
/* Destructor .. frees all space used by b */
  assert( b != NULL );
  FreeUnusedBins( b );
  free( b->bin_cnt );
  free( b );
  }
 

Back