Реализация

Artem Voroztsov - 02 Mar 2005

#include <stdio.h>
#include <malloc.h>

#define UNIQ_KEYS 1

typedef int mvalue_t;
typedef int mkey_t;

typedef enum {
   BT_ADDED,
   BT_UPDATED,
   BT_DELETED,
   BT_FOUND,
   BT_NOTFOUND,
   BT_ERROR,
} dt_result_t;


typedef struct dt {
   mvalue_t v;
      mkey_t x;
   int y;
      struct dt *l, *r;
} dt_t;

dt_t*
dt_search(dt_t *t, mkey_t x) {
    if ( t == NULL ) return NULL;
    if ( x < t->x ) return dt_search(t->l, x);
    if ( x > t->x ) return dt_search(t->r, x);
    return t;
}


void
dt_split(dt_t *t, mkey_t x, dt_t **l, dt_t **r) {
    if(t == NULL) {
       *r = *l = NULL;
    } else {
       if(x < t->x) {
            dt_split(t->l, x, l, r);
            t->l = *r; *r = t;
       } else {
            dt_split(t->r, x, l, r);
            t->r = *l; *l = t;
       }
    }
}

dt_t*
dt_merge(dt_t *l, dt_t *r) {
    if (l == NULL) return r;
    if (r == NULL) return l;
    if (l->y > r->y) {
       l->r = dt_merge(l->r,r);
       return l;
    } else {
       r->l = dt_merge(l,r->l);
       return r;
    }
}


inline dt_t* dt_newnode(mkey_t x, int y, mvalue_t v) {
    dt_t *t = (dt_t*) malloc(sizeof(dt_t));
    t->x = x; t->y = y, t->v = v;
    return t;
}

int
dt_insert(dt_t **t, mkey_t x, int y, mvalue_t v) {
    dt_t *tmp;
#ifdef UNIQ_KEYS
    tmp = dt_search(*t, x);
    if(tmp) {
       // printf("Replaced key %d value %d changed to %d\n", x, (*t)->v, v);
       tmp->v = v;
       return BT_UPDATED;
    }
#endif
    if (*t == NULL || y > (*t)->y) {
       tmp = dt_newnode(x, y, v);
       dt_split(*t, x, &(tmp->l), &(tmp->r));
       *t    = tmp;
       return BT_ADDED;
    } else if ( x < (*t)->x) {
       return dt_insert(&((*t)->l), x, y, v);
    } else {
       return dt_insert(&((*t)->r), x, y, v);
    }
}

int
dt_delete(dt_t **t, mkey_t x) {
    if ( *t == NULL ) return BT_NOTFOUND;
    if ( x < (*t)->x ) {
       return dt_delete( &((*t)->l), x);
    } else if ( x > (*t)->x) {
       return dt_delete( &((*t)->r), x);
    } else {
       dt_t *tmp = *t;
       *t = dt_merge((*t)->l, (*t)->r);
       free(tmp);
       return BT_ADDED;
    }
}

dt_t* dt_left(dt_t *t) {
    while(t->l != NULL) t = t->l;
    return t;
}

dt_t* dt_right(dt_t *t) {
    while(t->r != NULL) t = t->r;
    return t;
}