197bd480fSBaptiste Daroussin /* tree.h -- AVL trees (in the spirit of BSD's 'queue.h') -*- C -*- */ 297bd480fSBaptiste Daroussin 397bd480fSBaptiste Daroussin /* Copyright (c) 2005 Ian Piumarta 497bd480fSBaptiste Daroussin * 597bd480fSBaptiste Daroussin * All rights reserved. 697bd480fSBaptiste Daroussin * 797bd480fSBaptiste Daroussin * Permission is hereby granted, free of charge, to any person obtaining a copy 897bd480fSBaptiste Daroussin * of this software and associated documentation files (the 'Software'), to deal 997bd480fSBaptiste Daroussin * in the Software without restriction, including without limitation the rights 1097bd480fSBaptiste Daroussin * to use, copy, modify, merge, publish, distribute, and/or sell copies of the 1197bd480fSBaptiste Daroussin * Software, and to permit persons to whom the Software is furnished to do so, 1297bd480fSBaptiste Daroussin * provided that the above copyright notice(s) and this permission notice appear 1397bd480fSBaptiste Daroussin * in all copies of the Software and that both the above copyright notice(s) and 1497bd480fSBaptiste Daroussin * this permission notice appear in supporting documentation. 1597bd480fSBaptiste Daroussin * 1697bd480fSBaptiste Daroussin * THE SOFTWARE IS PROVIDED 'AS IS'. USE ENTIRELY AT YOUR OWN RISK. 1797bd480fSBaptiste Daroussin */ 1897bd480fSBaptiste Daroussin 1997bd480fSBaptiste Daroussin /* This file defines an AVL balanced binary tree [Georgii M. Adelson-Velskii and 2097bd480fSBaptiste Daroussin * Evgenii M. Landis, 'An algorithm for the organization of information', 2197bd480fSBaptiste Daroussin * Doklady Akademii Nauk SSSR, 146:263-266, 1962 (Russian). Also in Myron 2297bd480fSBaptiste Daroussin * J. Ricci (trans.), Soviet Math, 3:1259-1263, 1962 (English)]. 2397bd480fSBaptiste Daroussin * 2497bd480fSBaptiste Daroussin * An AVL tree is headed by pointers to the root node and to a function defining 2597bd480fSBaptiste Daroussin * the ordering relation between nodes. Each node contains an arbitrary payload 2697bd480fSBaptiste Daroussin * plus three fields per tree entry: the depth of the subtree for which it forms 2797bd480fSBaptiste Daroussin * the root and two pointers to child nodes (singly-linked for minimum space, at 2897bd480fSBaptiste Daroussin * the expense of direct access to the parent node given a pointer to one of the 2997bd480fSBaptiste Daroussin * children). The tree is rebalanced after every insertion or removal. The 3097bd480fSBaptiste Daroussin * tree may be traversed in two directions: forward (in-order left-to-right) and 3197bd480fSBaptiste Daroussin * reverse (in-order, right-to-left). 3297bd480fSBaptiste Daroussin * 3397bd480fSBaptiste Daroussin * Because of the recursive nature of many of the operations on trees it is 3497bd480fSBaptiste Daroussin * necessary to define a number of helper functions for each type of tree node. 3597bd480fSBaptiste Daroussin * The macro TREE_DEFINE(node_tag, entry_name) defines these functions with 3697bd480fSBaptiste Daroussin * unique names according to the node_tag. This macro should be invoked, 3797bd480fSBaptiste Daroussin * thereby defining the necessary functions, once per node tag in the program. 3897bd480fSBaptiste Daroussin * 3997bd480fSBaptiste Daroussin * For details on the use of these macros, see the tree(3) manual page. 4097bd480fSBaptiste Daroussin */ 4197bd480fSBaptiste Daroussin 4297bd480fSBaptiste Daroussin #ifndef __tree_h 4397bd480fSBaptiste Daroussin #define __tree_h 4497bd480fSBaptiste Daroussin 4597bd480fSBaptiste Daroussin 4697bd480fSBaptiste Daroussin #define TREE_DELTA_MAX 1 47*39ee7a7aSBaptiste Daroussin #ifndef _HU_FUNCTION 48*39ee7a7aSBaptiste Daroussin # if defined(__GNUC__) || defined(__clang__) 49*39ee7a7aSBaptiste Daroussin # define _HU_FUNCTION(x) __attribute__((__unused__)) x 50*39ee7a7aSBaptiste Daroussin # else 51*39ee7a7aSBaptiste Daroussin # define _HU_FUNCTION(x) x 52*39ee7a7aSBaptiste Daroussin # endif 53*39ee7a7aSBaptiste Daroussin #endif 5497bd480fSBaptiste Daroussin 5597bd480fSBaptiste Daroussin #define TREE_ENTRY(type) \ 5697bd480fSBaptiste Daroussin struct { \ 5797bd480fSBaptiste Daroussin struct type *avl_left; \ 5897bd480fSBaptiste Daroussin struct type *avl_right; \ 5997bd480fSBaptiste Daroussin int avl_height; \ 6097bd480fSBaptiste Daroussin } 6197bd480fSBaptiste Daroussin 6297bd480fSBaptiste Daroussin #define TREE_HEAD(name, type) \ 6397bd480fSBaptiste Daroussin struct name { \ 6497bd480fSBaptiste Daroussin struct type *th_root; \ 6597bd480fSBaptiste Daroussin int (*th_cmp)(struct type *lhs, struct type *rhs); \ 6697bd480fSBaptiste Daroussin } 6797bd480fSBaptiste Daroussin 6897bd480fSBaptiste Daroussin #define TREE_INITIALIZER(cmp) { 0, cmp } 6997bd480fSBaptiste Daroussin 7097bd480fSBaptiste Daroussin #define TREE_DELTA(self, field) \ 7197bd480fSBaptiste Daroussin (( (((self)->field.avl_left) ? (self)->field.avl_left->field.avl_height : 0)) \ 7297bd480fSBaptiste Daroussin - (((self)->field.avl_right) ? (self)->field.avl_right->field.avl_height : 0)) 7397bd480fSBaptiste Daroussin 7497bd480fSBaptiste Daroussin /* Recursion prevents the following from being defined as macros. */ 7597bd480fSBaptiste Daroussin 7697bd480fSBaptiste Daroussin #define TREE_DEFINE(node, field) \ 7797bd480fSBaptiste Daroussin \ 78*39ee7a7aSBaptiste Daroussin static struct node *_HU_FUNCTION(TREE_BALANCE_##node##_##field)(struct node *); \ 7997bd480fSBaptiste Daroussin \ 80*39ee7a7aSBaptiste Daroussin static struct node *_HU_FUNCTION(TREE_ROTL_##node##_##field)(struct node *self) \ 8197bd480fSBaptiste Daroussin { \ 8297bd480fSBaptiste Daroussin struct node *r= self->field.avl_right; \ 8397bd480fSBaptiste Daroussin self->field.avl_right= r->field.avl_left; \ 8497bd480fSBaptiste Daroussin r->field.avl_left= TREE_BALANCE_##node##_##field(self); \ 8597bd480fSBaptiste Daroussin return TREE_BALANCE_##node##_##field(r); \ 8697bd480fSBaptiste Daroussin } \ 8797bd480fSBaptiste Daroussin \ 88*39ee7a7aSBaptiste Daroussin static struct node *_HU_FUNCTION(TREE_ROTR_##node##_##field)(struct node *self) \ 8997bd480fSBaptiste Daroussin { \ 9097bd480fSBaptiste Daroussin struct node *l= self->field.avl_left; \ 9197bd480fSBaptiste Daroussin self->field.avl_left= l->field.avl_right; \ 9297bd480fSBaptiste Daroussin l->field.avl_right= TREE_BALANCE_##node##_##field(self); \ 9397bd480fSBaptiste Daroussin return TREE_BALANCE_##node##_##field(l); \ 9497bd480fSBaptiste Daroussin } \ 9597bd480fSBaptiste Daroussin \ 96*39ee7a7aSBaptiste Daroussin static struct node *_HU_FUNCTION(TREE_BALANCE_##node##_##field)(struct node *self) \ 9797bd480fSBaptiste Daroussin { \ 9897bd480fSBaptiste Daroussin int delta= TREE_DELTA(self, field); \ 9997bd480fSBaptiste Daroussin \ 10097bd480fSBaptiste Daroussin if (delta < -TREE_DELTA_MAX) \ 10197bd480fSBaptiste Daroussin { \ 10297bd480fSBaptiste Daroussin if (TREE_DELTA(self->field.avl_right, field) > 0) \ 10397bd480fSBaptiste Daroussin self->field.avl_right= TREE_ROTR_##node##_##field(self->field.avl_right); \ 10497bd480fSBaptiste Daroussin return TREE_ROTL_##node##_##field(self); \ 10597bd480fSBaptiste Daroussin } \ 10697bd480fSBaptiste Daroussin else if (delta > TREE_DELTA_MAX) \ 10797bd480fSBaptiste Daroussin { \ 10897bd480fSBaptiste Daroussin if (TREE_DELTA(self->field.avl_left, field) < 0) \ 10997bd480fSBaptiste Daroussin self->field.avl_left= TREE_ROTL_##node##_##field(self->field.avl_left); \ 11097bd480fSBaptiste Daroussin return TREE_ROTR_##node##_##field(self); \ 11197bd480fSBaptiste Daroussin } \ 11297bd480fSBaptiste Daroussin self->field.avl_height= 0; \ 11397bd480fSBaptiste Daroussin if (self->field.avl_left && (self->field.avl_left->field.avl_height > self->field.avl_height)) \ 11497bd480fSBaptiste Daroussin self->field.avl_height= self->field.avl_left->field.avl_height; \ 11597bd480fSBaptiste Daroussin if (self->field.avl_right && (self->field.avl_right->field.avl_height > self->field.avl_height)) \ 11697bd480fSBaptiste Daroussin self->field.avl_height= self->field.avl_right->field.avl_height; \ 11797bd480fSBaptiste Daroussin self->field.avl_height += 1; \ 11897bd480fSBaptiste Daroussin return self; \ 11997bd480fSBaptiste Daroussin } \ 12097bd480fSBaptiste Daroussin \ 121*39ee7a7aSBaptiste Daroussin static struct node *_HU_FUNCTION(TREE_INSERT_##node##_##field) \ 12297bd480fSBaptiste Daroussin (struct node *self, struct node *elm, int (*compare)(struct node *lhs, struct node *rhs)) \ 12397bd480fSBaptiste Daroussin { \ 12497bd480fSBaptiste Daroussin if (!self) \ 12597bd480fSBaptiste Daroussin return elm; \ 12697bd480fSBaptiste Daroussin if (compare(elm, self) < 0) \ 12797bd480fSBaptiste Daroussin self->field.avl_left= TREE_INSERT_##node##_##field(self->field.avl_left, elm, compare); \ 12897bd480fSBaptiste Daroussin else \ 12997bd480fSBaptiste Daroussin self->field.avl_right= TREE_INSERT_##node##_##field(self->field.avl_right, elm, compare); \ 13097bd480fSBaptiste Daroussin return TREE_BALANCE_##node##_##field(self); \ 13197bd480fSBaptiste Daroussin } \ 13297bd480fSBaptiste Daroussin \ 133*39ee7a7aSBaptiste Daroussin static struct node *_HU_FUNCTION(TREE_FIND_##node##_##field) \ 13497bd480fSBaptiste Daroussin (struct node *self, struct node *elm, int (*compare)(struct node *lhs, struct node *rhs)) \ 13597bd480fSBaptiste Daroussin { \ 13697bd480fSBaptiste Daroussin if (!self) \ 13797bd480fSBaptiste Daroussin return 0; \ 13897bd480fSBaptiste Daroussin if (compare(elm, self) == 0) \ 13997bd480fSBaptiste Daroussin return self; \ 14097bd480fSBaptiste Daroussin if (compare(elm, self) < 0) \ 14197bd480fSBaptiste Daroussin return TREE_FIND_##node##_##field(self->field.avl_left, elm, compare); \ 14297bd480fSBaptiste Daroussin else \ 14397bd480fSBaptiste Daroussin return TREE_FIND_##node##_##field(self->field.avl_right, elm, compare); \ 14497bd480fSBaptiste Daroussin } \ 14597bd480fSBaptiste Daroussin \ 146*39ee7a7aSBaptiste Daroussin static struct node *_HU_FUNCTION(TREE_MOVE_RIGHT)(struct node *self, struct node *rhs) \ 14797bd480fSBaptiste Daroussin { \ 14897bd480fSBaptiste Daroussin if (!self) \ 14997bd480fSBaptiste Daroussin return rhs; \ 15097bd480fSBaptiste Daroussin self->field.avl_right= TREE_MOVE_RIGHT(self->field.avl_right, rhs); \ 15197bd480fSBaptiste Daroussin return TREE_BALANCE_##node##_##field(self); \ 15297bd480fSBaptiste Daroussin } \ 15397bd480fSBaptiste Daroussin \ 154*39ee7a7aSBaptiste Daroussin static struct node *_HU_FUNCTION(TREE_REMOVE_##node##_##field) \ 15597bd480fSBaptiste Daroussin (struct node *self, struct node *elm, int (*compare)(struct node *lhs, struct node *rhs)) \ 15697bd480fSBaptiste Daroussin { \ 15797bd480fSBaptiste Daroussin if (!self) return 0; \ 15897bd480fSBaptiste Daroussin \ 15997bd480fSBaptiste Daroussin if (compare(elm, self) == 0) \ 16097bd480fSBaptiste Daroussin { \ 16197bd480fSBaptiste Daroussin struct node *tmp= TREE_MOVE_RIGHT(self->field.avl_left, self->field.avl_right); \ 16297bd480fSBaptiste Daroussin self->field.avl_left= 0; \ 16397bd480fSBaptiste Daroussin self->field.avl_right= 0; \ 16497bd480fSBaptiste Daroussin return tmp; \ 16597bd480fSBaptiste Daroussin } \ 16697bd480fSBaptiste Daroussin if (compare(elm, self) < 0) \ 16797bd480fSBaptiste Daroussin self->field.avl_left= TREE_REMOVE_##node##_##field(self->field.avl_left, elm, compare); \ 16897bd480fSBaptiste Daroussin else \ 16997bd480fSBaptiste Daroussin self->field.avl_right= TREE_REMOVE_##node##_##field(self->field.avl_right, elm, compare); \ 17097bd480fSBaptiste Daroussin return TREE_BALANCE_##node##_##field(self); \ 17197bd480fSBaptiste Daroussin } \ 17297bd480fSBaptiste Daroussin \ 173*39ee7a7aSBaptiste Daroussin static void _HU_FUNCTION(TREE_FORWARD_APPLY_ALL_##node##_##field) \ 17497bd480fSBaptiste Daroussin (struct node *self, void (*function)(struct node *node, void *data), void *data) \ 17597bd480fSBaptiste Daroussin { \ 17697bd480fSBaptiste Daroussin if (self) \ 17797bd480fSBaptiste Daroussin { \ 17897bd480fSBaptiste Daroussin TREE_FORWARD_APPLY_ALL_##node##_##field(self->field.avl_left, function, data); \ 17997bd480fSBaptiste Daroussin function(self, data); \ 18097bd480fSBaptiste Daroussin TREE_FORWARD_APPLY_ALL_##node##_##field(self->field.avl_right, function, data); \ 18197bd480fSBaptiste Daroussin } \ 18297bd480fSBaptiste Daroussin } \ 18397bd480fSBaptiste Daroussin \ 184*39ee7a7aSBaptiste Daroussin static void _HU_FUNCTION(TREE_REVERSE_APPLY_ALL_##node##_##field) \ 18597bd480fSBaptiste Daroussin (struct node *self, void (*function)(struct node *node, void *data), void *data) \ 18697bd480fSBaptiste Daroussin { \ 18797bd480fSBaptiste Daroussin if (self) \ 18897bd480fSBaptiste Daroussin { \ 18997bd480fSBaptiste Daroussin TREE_REVERSE_APPLY_ALL_##node##_##field(self->field.avl_right, function, data); \ 19097bd480fSBaptiste Daroussin function(self, data); \ 19197bd480fSBaptiste Daroussin TREE_REVERSE_APPLY_ALL_##node##_##field(self->field.avl_left, function, data); \ 19297bd480fSBaptiste Daroussin } \ 19397bd480fSBaptiste Daroussin } 19497bd480fSBaptiste Daroussin 19597bd480fSBaptiste Daroussin #define TREE_INSERT(head, node, field, elm) \ 19697bd480fSBaptiste Daroussin ((head)->th_root= TREE_INSERT_##node##_##field((head)->th_root, (elm), (head)->th_cmp)) 19797bd480fSBaptiste Daroussin 19897bd480fSBaptiste Daroussin #define TREE_FIND(head, node, field, elm) \ 19997bd480fSBaptiste Daroussin (TREE_FIND_##node##_##field((head)->th_root, (elm), (head)->th_cmp)) 20097bd480fSBaptiste Daroussin 20197bd480fSBaptiste Daroussin #define TREE_REMOVE(head, node, field, elm) \ 20297bd480fSBaptiste Daroussin ((head)->th_root= TREE_REMOVE_##node##_##field((head)->th_root, (elm), (head)->th_cmp)) 20397bd480fSBaptiste Daroussin 20497bd480fSBaptiste Daroussin #define TREE_DEPTH(head, field) \ 20597bd480fSBaptiste Daroussin ((head)->th_root->field.avl_height) 20697bd480fSBaptiste Daroussin 20797bd480fSBaptiste Daroussin #define TREE_FORWARD_APPLY(head, node, field, function, data) \ 20897bd480fSBaptiste Daroussin TREE_FORWARD_APPLY_ALL_##node##_##field((head)->th_root, function, data) 20997bd480fSBaptiste Daroussin 21097bd480fSBaptiste Daroussin #define TREE_REVERSE_APPLY(head, node, field, function, data) \ 21197bd480fSBaptiste Daroussin TREE_REVERSE_APPLY_ALL_##node##_##field((head)->th_root, function, data) 21297bd480fSBaptiste Daroussin 21397bd480fSBaptiste Daroussin #define TREE_INIT(head, cmp) do { \ 21497bd480fSBaptiste Daroussin (head)->th_root= 0; \ 21597bd480fSBaptiste Daroussin (head)->th_cmp= (cmp); \ 21697bd480fSBaptiste Daroussin } while (0) 21797bd480fSBaptiste Daroussin 21897bd480fSBaptiste Daroussin 21997bd480fSBaptiste Daroussin #endif /* __tree_h */ 220