AVLTree
view release on metacpan or search on metacpan
avltree/avltree.c view on Meta::CPAN
/*
AVL balanced tree library
This is an adaptation of the AVL balanced tree C library
created by Julienne Walker which can be found here:
http://www.eternallyconfuzzled.com/Libraries.aspx
*/
#include "avltree.h"
#ifdef __cplusplus
#include <cstdlib>
using std::malloc;
using std::free;
using std::size_t;
#else
#include <stdlib.h>
#include <stdio.h>
#endif
#ifndef HEIGHT_LIMIT
#define HEIGHT_LIMIT 64 /* Tallest allowable tree */
#endif
typedef struct avlnode {
int balance; /* Balance factor */
SV *data; /* User-defined content */
struct avlnode *link[2]; /* Left (0) and right (1) links */
} avlnode_t;
struct avltree {
avlnode_t *root; /* Top of the tree */
cmp_f cmp; /* Compare two items */
dup_f dup; /* Clone an item (user-defined) */
rel_f rel; /* Destroy an item (user-defined) */
size_t size; /* Number of items (user-defined) */
};
struct avltrav {
avltree_t *tree; /* Paired tree */
avlnode_t *it; /* Current node */
avlnode_t *path[HEIGHT_LIMIT]; /* Traversal path */
size_t top; /* Top of stack */
};
/* Two way single rotation */
#define single(root,dir) do { \
avlnode_t *save = root->link[!dir]; \
root->link[!dir] = save->link[dir]; \
save->link[dir] = root; \
root = save; \
} while (0)
/* Two way double rotation */
#define double(root,dir) do { \
avlnode_t *save = root->link[!dir]->link[dir]; \
root->link[!dir]->link[dir] = save->link[!dir]; \
save->link[!dir] = root->link[!dir]; \
root->link[!dir] = save; \
save = root->link[!dir]; \
root->link[!dir] = save->link[dir]; \
save->link[dir] = root; \
root = save; \
} while (0)
/* Adjust balance before double rotation */
#define adjust_balance(root,dir,bal) do { \
avlnode_t *n = root->link[dir]; \
avlnode_t *nn = n->link[!dir]; \
if ( nn->balance == 0 ) \
root->balance = n->balance = 0; \
else if ( nn->balance == bal ) { \
root->balance = -bal; \
n->balance = 0; \
} \
else { /* nn->balance == -bal */ \
root->balance = 0; \
n->balance = bal; \
} \
nn->balance = 0; \
} while (0)
/* Rebalance after insertion */
#define insert_balance(root,dir) do { \
avlnode_t *n = root->link[dir]; \
( run in 0.498 second using v1.01-cache-2.11-cpan-df04353d9ac )