/*
  tree.h acts as the header file for both 
  threaded and unthreaded versions of my tree-based algorithms, and 
  thus defines `tag' as part of struct point, as the addition of a 
  short probably doesn't change much w.r.t. the run-time 
  performance of the code.  If you use the unthreaded algorithms 
  feel free to delete tag from struct point.  I doubt if it will 
  make much difference to how the thing runs (and it certainly 
  shouldn't result in any errors).
*/

#include <stdio.h>
#include <math.h>

#include "rand41.h"
#define exp1(tseed) (-log(rand1(tseed)))

typedef struct{
  double x;
  double y;
}coord;

typedef struct point point;
struct point {
  short min_life;
  short tag;  /* Are left and right node-pointers or threads? */
	      /* 0=left\&right nodes, 1=left node, right thread, */
	      /* 2=left thread, right node, 3=left\&right threads. */
  double birth;
  double death;
  double mark;
  coord pos;
  point *left;
  point *right;
};

point *insert_dom(point *tree,       /* Insert a new node in the */
		  point *npoint);    /* tree according to it's */
				     /* birth time.  Smallest birth */
				     /* time is left-most. */

point *insert_real(point *tree,      /* Insert a new node in the */
		   point *npoint);   /* tree according to it's */
				     /* death time.  Largest death */
				     /* time is left-most. */

point *remove_left(point *tree);     /* Delete left-most node of */
				     /* tree, connecting any loose */
				     /* ends created */

void applyinorder(point *tree,
		  void (*fn)(point *,void *),
		  void *arg);

int testinorder(point *tree,
		int (*fn)(point *));

point *left(point *tree); /* Find left-most node of tree */

point *birth_to_death(point *tree); /* Transform tree from one */
				    /* ordered by birth times to */
				    /* one ordered by death times.  */
				    /* WARNING: This function */
				    /* deletes the old tree!!! */

point *newnode(double deathtime,   /* Initialize new point */
	       long *tseed,        /* min\_life is NOT initialized */
	       long *mseed,        /* by this routine */
	       long *pseed
	       );

point *copynode(point *oldnode);  /* Copy oldnode to a new one.  As */
				  /* is suitable for new nodes we */
				  /* initialize pointers.  Tags are */
				  /* initialised automatically upon */
				  /* insertion, so need no */
				  /* initialization/copying */

void printcoord(point *p,      /* Print the x and y coordinates */
		void *arg      /* according to the format passed */
		);             /* in arg */
