1*fa9922c2SRobert Mustacchi.\" 2*fa9922c2SRobert Mustacchi.\" This file and its contents are supplied under the terms of the 3*fa9922c2SRobert Mustacchi.\" Common Development and Distribution License ("CDDL"), version 1.0. 4*fa9922c2SRobert Mustacchi.\" You may only use this file in accordance with the terms of version 5*fa9922c2SRobert Mustacchi.\" 1.0 of the CDDL. 6*fa9922c2SRobert Mustacchi.\" 7*fa9922c2SRobert Mustacchi.\" A full copy of the text of the CDDL should have accompanied this 8*fa9922c2SRobert Mustacchi.\" source. A copy of the CDDL is also available via the Internet at 9*fa9922c2SRobert Mustacchi.\" http://www.illumos.org/license/CDDL. 10*fa9922c2SRobert Mustacchi.\" 11*fa9922c2SRobert Mustacchi.\" 12*fa9922c2SRobert Mustacchi.\" Copyright 2015 Joyent, Inc. 13*fa9922c2SRobert Mustacchi.\" 14*fa9922c2SRobert Mustacchi.Dd May 07, 2015 15*fa9922c2SRobert Mustacchi.Dt LIBAVL 3LIB 16*fa9922c2SRobert Mustacchi.Os 17*fa9922c2SRobert Mustacchi.Sh NAME 18*fa9922c2SRobert Mustacchi.Nm libavl 19*fa9922c2SRobert Mustacchi.Nd generic self-balancing binary search tree library 20*fa9922c2SRobert Mustacchi.Sh SYNOPSIS 21*fa9922c2SRobert Mustacchi.Lb libavl 22*fa9922c2SRobert Mustacchi.In sys/avl.h 23*fa9922c2SRobert Mustacchi.Sh DESCRIPTION 24*fa9922c2SRobert MustacchiThe 25*fa9922c2SRobert Mustacchi.Nm 26*fa9922c2SRobert Mustacchilibrary provides a generic implementation of AVL trees, a form of 27*fa9922c2SRobert Mustacchiself-balancing binary tree. The interfaces provided allow for an 28*fa9922c2SRobert Mustacchiefficient way of implementing an ordered set of data structures and, due 29*fa9922c2SRobert Mustacchito its embeddable nature, allow for a single instance of a data 30*fa9922c2SRobert Mustacchistructure to belong to multiple AVL trees. 31*fa9922c2SRobert Mustacchi.Lp 32*fa9922c2SRobert MustacchiEach AVL tree contains entries of a single type of data structure. 33*fa9922c2SRobert MustacchiRather than allocating memory for pointers for those data structures, 34*fa9922c2SRobert Mustacchithe storage for the tree is embedded into the data structures by 35*fa9922c2SRobert Mustacchideclaring a member of type 36*fa9922c2SRobert Mustacchi.Vt avl_node_t . 37*fa9922c2SRobert MustacchiWhen an AVL tree is created, through the use of 38*fa9922c2SRobert Mustacchi.Fn avl_create , 39*fa9922c2SRobert Mustacchiit encodes the size of the data structure, the offset of the data 40*fa9922c2SRobert Mustacchistructure, and a comparator function which is used to compare two 41*fa9922c2SRobert Mustacchiinstances of a data structure. A data structure may be a member of 42*fa9922c2SRobert Mustacchimultiple AVL trees by creating AVL trees which use different 43*fa9922c2SRobert Mustacchioffsets (different members) into the data structure. 44*fa9922c2SRobert Mustacchi.Lp 45*fa9922c2SRobert MustacchiAVL trees support both look up of an arbitrary item and ordered 46*fa9922c2SRobert Mustacchiiteration over the contents of the entire tree. In addition, from any 47*fa9922c2SRobert Mustacchinode, you can find the previous and next entries in the tree, if they 48*fa9922c2SRobert Mustacchiexist. In addition, AVL trees support arbitrary insertion and deletion. 49*fa9922c2SRobert Mustacchi.Ss Performance 50*fa9922c2SRobert MustacchiAVL trees are often used in place of linked lists. Compared to the 51*fa9922c2SRobert Mustacchistandard, intrusive, doubly linked list, it has the following 52*fa9922c2SRobert Mustacchiperformance characteristics: 53*fa9922c2SRobert Mustacchi.Bl -hang -width Ds 54*fa9922c2SRobert Mustacchi.It Sy Lookup One Node 55*fa9922c2SRobert Mustacchi.Bd -filled -compact 56*fa9922c2SRobert MustacchiLookup of a single node in a linked list is 57*fa9922c2SRobert Mustacchi.Sy O(n) , 58*fa9922c2SRobert Mustacchiwhereas lookup of a single node in an AVL tree is 59*fa9922c2SRobert Mustacchi.Sy O(log(n)) . 60*fa9922c2SRobert Mustacchi.Ed 61*fa9922c2SRobert Mustacchi.It Sy Insert One Node 62*fa9922c2SRobert Mustacchi.Bd -filled -compact 63*fa9922c2SRobert MustacchiInserting a single node into a linked list is 64*fa9922c2SRobert Mustacchi.Sy O(1) . 65*fa9922c2SRobert MustacchiInserting a single node into an AVL tree is 66*fa9922c2SRobert Mustacchi.Sy O(log(n)) . 67*fa9922c2SRobert Mustacchi.Pp 68*fa9922c2SRobert MustacchiNote, insertions into an AVL tree always result in an ordered tree. 69*fa9922c2SRobert MustacchiInsertions into a linked list do not guarantee order. If order is 70*fa9922c2SRobert Mustacchirequired, then the time to do the insertion into a linked list will 71*fa9922c2SRobert Mustacchidepend on the time of the search algorithm being employed to find the 72*fa9922c2SRobert Mustacchiplace to insert at. 73*fa9922c2SRobert Mustacchi.Ed 74*fa9922c2SRobert Mustacchi.It Sy Delete One Node 75*fa9922c2SRobert Mustacchi.Bd -filled -compact 76*fa9922c2SRobert MustacchiDeleting a single node from a linked list is 77*fa9922c2SRobert Mustacchi.Sy O(1), 78*fa9922c2SRobert Mustacchiwhereas deleting a single node from an AVL tree takes 79*fa9922c2SRobert Mustacchi.Sy O(log(n)) 80*fa9922c2SRobert Mustacchitime. 81*fa9922c2SRobert Mustacchi.Ed 82*fa9922c2SRobert Mustacchi.It Sy Delete All Nodes 83*fa9922c2SRobert Mustacchi.Bd -filled -compact 84*fa9922c2SRobert MustacchiDeleting all nodes from a linked list is 85*fa9922c2SRobert Mustacchi.Sy O(n) . 86*fa9922c2SRobert MustacchiWith an AVL tree, if using the 87*fa9922c2SRobert Mustacchi.Xr avl_delete_nodes 3AVL 88*fa9922c2SRobert Mustacchifunction then deleting all nodes 89*fa9922c2SRobert Mustacchiis 90*fa9922c2SRobert Mustacchi.Sy O(n) . 91*fa9922c2SRobert MustacchiHowever, if iterating over each entry in the tree and then removing it using 92*fa9922c2SRobert Mustacchia while loop, 93*fa9922c2SRobert Mustacchi.Xr avl_first 3AVL 94*fa9922c2SRobert Mustacchiand 95*fa9922c2SRobert Mustacchi.Xr avl_remove 3AVL 96*fa9922c2SRobert Mustacchithen the time to remove all nodes is 97*fa9922c2SRobert Mustacchi.Sy O(n\ *\ log(n)). 98*fa9922c2SRobert Mustacchi.Ed 99*fa9922c2SRobert Mustacchi.It Sy Visit the Next or Previous Node 100*fa9922c2SRobert Mustacchi.Bd -filled -compact 101*fa9922c2SRobert MustacchiVisiting the next or previous node in a linked list is 102*fa9922c2SRobert Mustacchi.Sy O(1) , 103*fa9922c2SRobert Mustacchiwhereas going from the next to the previous node in an AVL tree will 104*fa9922c2SRobert Mustacchitake between 105*fa9922c2SRobert Mustacchi.Sy O(1) 106*fa9922c2SRobert Mustacchiand 107*fa9922c2SRobert Mustacchi.Sy O(log(n)) . 108*fa9922c2SRobert Mustacchi.Ed 109*fa9922c2SRobert Mustacchi.El 110*fa9922c2SRobert Mustacchi.Pp 111*fa9922c2SRobert MustacchiIn general, AVL trees are a good alternative for linked lists when order 112*fa9922c2SRobert Mustacchior lookup speed is important and a reasonable number of items will be 113*fa9922c2SRobert Mustacchipresent. 114*fa9922c2SRobert Mustacchi.Sh INTERFACES 115*fa9922c2SRobert MustacchiThe shared object 116*fa9922c2SRobert Mustacchi.Sy libavl.so.1 117*fa9922c2SRobert Mustacchiprovides the public interfaces defined below. See 118*fa9922c2SRobert Mustacchi.Xr Intro(3) 119*fa9922c2SRobert Mustacchifor additional information on shared object interfaces. Individual 120*fa9922c2SRobert Mustacchifunctions are documented in their own manual pages. 121*fa9922c2SRobert Mustacchi.Bl -column -offset indent ".Sy avl_is_empty" ".Sy avl_destroy_nodes" 122*fa9922c2SRobert Mustacchi.It Sy avl_add Ta Sy avl_create 123*fa9922c2SRobert Mustacchi.It Sy avl_destroy Ta Sy avl_destroy_nodes 124*fa9922c2SRobert Mustacchi.It Sy avl_find Ta Sy avl_first 125*fa9922c2SRobert Mustacchi.It Sy avl_insert Ta Sy avl_insert_here 126*fa9922c2SRobert Mustacchi.It Sy avl_is_empty Ta Sy avl_last 127*fa9922c2SRobert Mustacchi.It Sy avl_nearest Ta Sy avl_numnodes 128*fa9922c2SRobert Mustacchi.It Sy avl_remove Ta Sy avl_swap 129*fa9922c2SRobert Mustacchi.El 130*fa9922c2SRobert Mustacchi.Pp 131*fa9922c2SRobert MustacchiIn addition, the library defines C pre-processor macros which are 132*fa9922c2SRobert Mustacchidefined below and documented in their own manual pages. 133*fa9922c2SRobert Mustacchi.\" 134*fa9922c2SRobert Mustacchi.\" Use the same column widths in both cases where we describe the list 135*fa9922c2SRobert Mustacchi.\" of interfaces, to allow the manual page to better line up when rendered. 136*fa9922c2SRobert Mustacchi.\" 137*fa9922c2SRobert Mustacchi.Bl -column -offset indent ".Sy avl_is_empty" ".Sy avl_destroy_nodes" 138*fa9922c2SRobert Mustacchi.It Sy AVL_NEXT Ta Sy AVL_PREV 139*fa9922c2SRobert Mustacchi.El 140*fa9922c2SRobert Mustacchi.Sh TYPES 141*fa9922c2SRobert MustacchiThe 142*fa9922c2SRobert Mustacchi.Nm 143*fa9922c2SRobert Mustacchilibrary defines the following types: 144*fa9922c2SRobert Mustacchi.Lp 145*fa9922c2SRobert Mustacchi.Sy avl_tree_t 146*fa9922c2SRobert Mustacchi.Lp 147*fa9922c2SRobert MustacchiType used for the root of the AVL tree. Consumers define one of these 148*fa9922c2SRobert Mustacchifor each of the different trees that they want to have. 149*fa9922c2SRobert Mustacchi.Lp 150*fa9922c2SRobert Mustacchi.Sy avl_node_t 151*fa9922c2SRobert Mustacchi.Lp 152*fa9922c2SRobert MustacchiType used as the data node for an AVL tree. One of these is embedded in 153*fa9922c2SRobert Mustacchieach data structure that is the member of an AVL tree. 154*fa9922c2SRobert Mustacchi.Lp 155*fa9922c2SRobert Mustacchi.Sy avl_index_t 156*fa9922c2SRobert Mustacchi.Lp 157*fa9922c2SRobert MustacchiType used to locate a position in a tree. This is used with 158*fa9922c2SRobert Mustacchi.Xr avl_find 3AVL 159*fa9922c2SRobert Mustacchiand 160*fa9922c2SRobert Mustacchi.Xr avl_insert 3AVL . 161*fa9922c2SRobert Mustacchi.Sh LOCKING 162*fa9922c2SRobert MustacchiThe 163*fa9922c2SRobert Mustacchi.Nm 164*fa9922c2SRobert Mustacchilibrary provides no locking. Callers that are using the same AVL tree 165*fa9922c2SRobert Mustacchifrom multiple threads need to provide their own synchronization. If only 166*fa9922c2SRobert Mustacchione thread is ever accessing or modifying the AVL tree, then there are 167*fa9922c2SRobert Mustacchino synchronization concerns. If multiple AVL trees exist, then they may 168*fa9922c2SRobert Mustacchiall be used simultaneously; however, they are subject to the same rules 169*fa9922c2SRobert Mustacchiaround simultaneous access from a single thread. 170*fa9922c2SRobert Mustacchi.Lp 171*fa9922c2SRobert MustacchiAll routines are both 172*fa9922c2SRobert Mustacchi.Sy Fork-safe 173*fa9922c2SRobert Mustacchiand 174*fa9922c2SRobert Mustacchi.Sy Async-Signal-Safe . 175*fa9922c2SRobert MustacchiCallers may call functions in 176*fa9922c2SRobert Mustacchi.Nm 177*fa9922c2SRobert Mustacchifrom a signal handler and 178*fa9922c2SRobert Mustacchi.Nm 179*fa9922c2SRobert Mustacchicalls are all safe in face of 180*fa9922c2SRobert Mustacchi.Xr fork 2 ; 181*fa9922c2SRobert Mustacchihowever, if callers have their own locks, then they must make sure that 182*fa9922c2SRobert Mustacchithey are accounted for by the use of routines such as 183*fa9922c2SRobert Mustacchi.Xr pthread_atfork 3C . 184*fa9922c2SRobert Mustacchi.Sh EXAMPLES 185*fa9922c2SRobert MustacchiThe following code shows examples of exercising all of the functionality 186*fa9922c2SRobert Mustacchithat is present in 187*fa9922c2SRobert Mustacchi.Nm . 188*fa9922c2SRobert MustacchiIt can be compiled by using a C compiler and linking 189*fa9922c2SRobert Mustacchiagainst 190*fa9922c2SRobert Mustacchi.Nm . 191*fa9922c2SRobert MustacchiFor example, given a file named avl.c, with gcc, one would run: 192*fa9922c2SRobert Mustacchi.Bd -literal 193*fa9922c2SRobert Mustacchi$ gcc -Wall -o avl avl.c -lavl 194*fa9922c2SRobert Mustacchi.Ed 195*fa9922c2SRobert Mustacchi.Bd -literal 196*fa9922c2SRobert Mustacchi/* 197*fa9922c2SRobert Mustacchi * Example of using AVL Trees 198*fa9922c2SRobert Mustacchi */ 199*fa9922c2SRobert Mustacchi 200*fa9922c2SRobert Mustacchi#include <sys/avl.h> 201*fa9922c2SRobert Mustacchi#include <stddef.h> 202*fa9922c2SRobert Mustacchi#include <stdlib.h> 203*fa9922c2SRobert Mustacchi#include <stdio.h> 204*fa9922c2SRobert Mustacchi 205*fa9922c2SRobert Mustacchistatic avl_tree_t inttree; 206*fa9922c2SRobert Mustacchi 207*fa9922c2SRobert Mustacchi/* 208*fa9922c2SRobert Mustacchi * The structure that we're storing in an AVL tree. 209*fa9922c2SRobert Mustacchi */ 210*fa9922c2SRobert Mustacchitypedef struct intnode { 211*fa9922c2SRobert Mustacchi int in_val; 212*fa9922c2SRobert Mustacchi avl_node_t in_avl; 213*fa9922c2SRobert Mustacchi} intnode_t; 214*fa9922c2SRobert Mustacchi 215*fa9922c2SRobert Mustacchistatic int 216*fa9922c2SRobert Mustacchiintnode_comparator(const void *l, const void *r) 217*fa9922c2SRobert Mustacchi{ 218*fa9922c2SRobert Mustacchi const intnode_t *li = l; 219*fa9922c2SRobert Mustacchi const intnode_t *ri = r; 220*fa9922c2SRobert Mustacchi 221*fa9922c2SRobert Mustacchi if (li->in_val > ri->in_val) 222*fa9922c2SRobert Mustacchi return (1); 223*fa9922c2SRobert Mustacchi if (li->in_val < ri->in_val) 224*fa9922c2SRobert Mustacchi return (-1); 225*fa9922c2SRobert Mustacchi return (0); 226*fa9922c2SRobert Mustacchi} 227*fa9922c2SRobert Mustacchi 228*fa9922c2SRobert Mustacchi/* 229*fa9922c2SRobert Mustacchi * Create an AVL Tree 230*fa9922c2SRobert Mustacchi */ 231*fa9922c2SRobert Mustacchistatic void 232*fa9922c2SRobert Mustacchicreate_avl(void) 233*fa9922c2SRobert Mustacchi{ 234*fa9922c2SRobert Mustacchi avl_create(&inttree, intnode_comparator, sizeof (intnode_t), 235*fa9922c2SRobert Mustacchi offsetof(intnode_t, in_avl)); 236*fa9922c2SRobert Mustacchi} 237*fa9922c2SRobert Mustacchi 238*fa9922c2SRobert Mustacchi/* 239*fa9922c2SRobert Mustacchi * Add entries to the tree with the avl_add function. 240*fa9922c2SRobert Mustacchi */ 241*fa9922c2SRobert Mustacchistatic void 242*fa9922c2SRobert Mustacchifill_avl(void) 243*fa9922c2SRobert Mustacchi{ 244*fa9922c2SRobert Mustacchi int i; 245*fa9922c2SRobert Mustacchi intnode_t *inp; 246*fa9922c2SRobert Mustacchi 247*fa9922c2SRobert Mustacchi for (i = 0; i < 20; i++) { 248*fa9922c2SRobert Mustacchi inp = malloc(sizeof (intnode_t)); 249*fa9922c2SRobert Mustacchi assert(inp != NULL); 250*fa9922c2SRobert Mustacchi inp->in_val = i; 251*fa9922c2SRobert Mustacchi avl_add(&inttree, inp); 252*fa9922c2SRobert Mustacchi } 253*fa9922c2SRobert Mustacchi} 254*fa9922c2SRobert Mustacchi 255*fa9922c2SRobert Mustacchi/* 256*fa9922c2SRobert Mustacchi * Find entries in the AVL tree. Note, we create an intnode_t on the 257*fa9922c2SRobert Mustacchi * stack that we use to look this up. 258*fa9922c2SRobert Mustacchi */ 259*fa9922c2SRobert Mustacchistatic void 260*fa9922c2SRobert Mustacchifind_avl(void) 261*fa9922c2SRobert Mustacchi{ 262*fa9922c2SRobert Mustacchi int i; 263*fa9922c2SRobert Mustacchi intnode_t lookup, *inp; 264*fa9922c2SRobert Mustacchi 265*fa9922c2SRobert Mustacchi for (i = 10; i < 30; i++) { 266*fa9922c2SRobert Mustacchi lookup.in_val = i; 267*fa9922c2SRobert Mustacchi inp = avl_find(&inttree, &lookup, NULL); 268*fa9922c2SRobert Mustacchi if (inp == NULL) { 269*fa9922c2SRobert Mustacchi printf("Entry %d is not in the tree\\n", i); 270*fa9922c2SRobert Mustacchi } else { 271*fa9922c2SRobert Mustacchi printf("Entry %d is in the tree\\n", 272*fa9922c2SRobert Mustacchi inp->in_val); 273*fa9922c2SRobert Mustacchi } 274*fa9922c2SRobert Mustacchi } 275*fa9922c2SRobert Mustacchi} 276*fa9922c2SRobert Mustacchi 277*fa9922c2SRobert Mustacchi/* 278*fa9922c2SRobert Mustacchi * Walk the tree forwards 279*fa9922c2SRobert Mustacchi */ 280*fa9922c2SRobert Mustacchistatic void 281*fa9922c2SRobert Mustacchiwalk_forwards(void) 282*fa9922c2SRobert Mustacchi{ 283*fa9922c2SRobert Mustacchi intnode_t *inp; 284*fa9922c2SRobert Mustacchi for (inp = avl_first(&inttree); inp != NULL; 285*fa9922c2SRobert Mustacchi inp = AVL_NEXT(&inttree, inp)) { 286*fa9922c2SRobert Mustacchi printf("Found entry %d\\n", inp->in_val); 287*fa9922c2SRobert Mustacchi } 288*fa9922c2SRobert Mustacchi} 289*fa9922c2SRobert Mustacchi 290*fa9922c2SRobert Mustacchi/* 291*fa9922c2SRobert Mustacchi * Walk the tree backwards. 292*fa9922c2SRobert Mustacchi */ 293*fa9922c2SRobert Mustacchistatic void 294*fa9922c2SRobert Mustacchiwalk_backwards(void) 295*fa9922c2SRobert Mustacchi{ 296*fa9922c2SRobert Mustacchi intnode_t *inp; 297*fa9922c2SRobert Mustacchi for (inp = avl_last(&inttree); inp != NULL; 298*fa9922c2SRobert Mustacchi inp = AVL_PREV(&inttree, inp)) { 299*fa9922c2SRobert Mustacchi printf("Found entry %d\\n", inp->in_val); 300*fa9922c2SRobert Mustacchi } 301*fa9922c2SRobert Mustacchi} 302*fa9922c2SRobert Mustacchi 303*fa9922c2SRobert Mustacchi/* 304*fa9922c2SRobert Mustacchi * Determine the number of nodes in the tree and if it is empty or 305*fa9922c2SRobert Mustacchi * not. 306*fa9922c2SRobert Mustacchi */ 307*fa9922c2SRobert Mustacchistatic void 308*fa9922c2SRobert Mustacchiinttree_inspect(void) 309*fa9922c2SRobert Mustacchi{ 310*fa9922c2SRobert Mustacchi printf("The tree is %s, there are %ld nodes in it\\n", 311*fa9922c2SRobert Mustacchi avl_is_empty(&inttree) == B_TRUE ? "empty" : "not empty", 312*fa9922c2SRobert Mustacchi avl_numnodes(&inttree)); 313*fa9922c2SRobert Mustacchi} 314*fa9922c2SRobert Mustacchi 315*fa9922c2SRobert Mustacchi/* 316*fa9922c2SRobert Mustacchi * Use avl_remove to remove entries from the tree. 317*fa9922c2SRobert Mustacchi */ 318*fa9922c2SRobert Mustacchistatic void 319*fa9922c2SRobert Mustacchiremove_nodes(void) 320*fa9922c2SRobert Mustacchi{ 321*fa9922c2SRobert Mustacchi int i; 322*fa9922c2SRobert Mustacchi intnode_t lookup, *inp; 323*fa9922c2SRobert Mustacchi 324*fa9922c2SRobert Mustacchi for (i = 0; i < 20; i+= 4) { 325*fa9922c2SRobert Mustacchi lookup.in_val = i; 326*fa9922c2SRobert Mustacchi inp = avl_find(&inttree, &lookup, NULL); 327*fa9922c2SRobert Mustacchi if (inp != NULL) 328*fa9922c2SRobert Mustacchi avl_remove(&inttree, inp); 329*fa9922c2SRobert Mustacchi } 330*fa9922c2SRobert Mustacchi} 331*fa9922c2SRobert Mustacchi 332*fa9922c2SRobert Mustacchi/* 333*fa9922c2SRobert Mustacchi * Find the nearest nodes in the tree. 334*fa9922c2SRobert Mustacchi */ 335*fa9922c2SRobert Mustacchistatic void 336*fa9922c2SRobert Mustacchinearest_nodes(void) 337*fa9922c2SRobert Mustacchi{ 338*fa9922c2SRobert Mustacchi intnode_t lookup, *inp; 339*fa9922c2SRobert Mustacchi avl_index_t where; 340*fa9922c2SRobert Mustacchi 341*fa9922c2SRobert Mustacchi lookup.in_val = 12; 342*fa9922c2SRobert Mustacchi if (avl_find(&inttree, &lookup, &where) != NULL) 343*fa9922c2SRobert Mustacchi abort(); 344*fa9922c2SRobert Mustacchi inp = avl_nearest(&inttree, where, AVL_BEFORE); 345*fa9922c2SRobert Mustacchi assert(inp != NULL); 346*fa9922c2SRobert Mustacchi printf("closest node before 12 is: %d\\n", inp->in_val); 347*fa9922c2SRobert Mustacchi inp = avl_nearest(&inttree, where, AVL_AFTER); 348*fa9922c2SRobert Mustacchi assert(inp != NULL); 349*fa9922c2SRobert Mustacchi printf("closest node after 12 is: %d\\n", inp->in_val); 350*fa9922c2SRobert Mustacchi} 351*fa9922c2SRobert Mustacchi 352*fa9922c2SRobert Mustacchistatic void 353*fa9922c2SRobert Mustacchiinsert_avl(void) 354*fa9922c2SRobert Mustacchi{ 355*fa9922c2SRobert Mustacchi intnode_t lookup, *inp; 356*fa9922c2SRobert Mustacchi avl_index_t where; 357*fa9922c2SRobert Mustacchi 358*fa9922c2SRobert Mustacchi lookup.in_val = 12; 359*fa9922c2SRobert Mustacchi if (avl_find(&inttree, &lookup, &where) != NULL) 360*fa9922c2SRobert Mustacchi abort(); 361*fa9922c2SRobert Mustacchi inp = malloc(sizeof (intnode_t)); 362*fa9922c2SRobert Mustacchi assert(inp != NULL); 363*fa9922c2SRobert Mustacchi avl_insert(&inttree, inp, where); 364*fa9922c2SRobert Mustacchi} 365*fa9922c2SRobert Mustacchi 366*fa9922c2SRobert Mustacchistatic void 367*fa9922c2SRobert Mustacchiswap_avl(void) 368*fa9922c2SRobert Mustacchi{ 369*fa9922c2SRobert Mustacchi avl_tree_t swap; 370*fa9922c2SRobert Mustacchi 371*fa9922c2SRobert Mustacchi avl_create(&swap, intnode_comparator, sizeof (intnode_t), 372*fa9922c2SRobert Mustacchi offsetof(intnode_t, in_avl)); 373*fa9922c2SRobert Mustacchi avl_swap(&inttree, &swap); 374*fa9922c2SRobert Mustacchi inttree_inspect(); 375*fa9922c2SRobert Mustacchi avl_swap(&inttree, &swap); 376*fa9922c2SRobert Mustacchi inttree_inspect(); 377*fa9922c2SRobert Mustacchi} 378*fa9922c2SRobert Mustacchi 379*fa9922c2SRobert Mustacchi/* 380*fa9922c2SRobert Mustacchi * Remove all remaining nodes in the tree. We first use 381*fa9922c2SRobert Mustacchi * avl_destroy_nodes to empty the tree, then avl_destroy to finish. 382*fa9922c2SRobert Mustacchi */ 383*fa9922c2SRobert Mustacchistatic void 384*fa9922c2SRobert Mustacchicleanup(void) 385*fa9922c2SRobert Mustacchi{ 386*fa9922c2SRobert Mustacchi intnode_t *inp; 387*fa9922c2SRobert Mustacchi void *c = NULL; 388*fa9922c2SRobert Mustacchi 389*fa9922c2SRobert Mustacchi while ((inp = avl_destroy_nodes(&inttree, &c)) != NULL) { 390*fa9922c2SRobert Mustacchi free(inp); 391*fa9922c2SRobert Mustacchi } 392*fa9922c2SRobert Mustacchi avl_destroy(&inttree); 393*fa9922c2SRobert Mustacchi} 394*fa9922c2SRobert Mustacchi 395*fa9922c2SRobert Mustacchiint 396*fa9922c2SRobert Mustacchimain(void) 397*fa9922c2SRobert Mustacchi{ 398*fa9922c2SRobert Mustacchi create_avl(); 399*fa9922c2SRobert Mustacchi inttree_inspect(); 400*fa9922c2SRobert Mustacchi fill_avl(); 401*fa9922c2SRobert Mustacchi find_avl(); 402*fa9922c2SRobert Mustacchi walk_forwards(); 403*fa9922c2SRobert Mustacchi walk_backwards(); 404*fa9922c2SRobert Mustacchi inttree_inspect(); 405*fa9922c2SRobert Mustacchi remove_nodes(); 406*fa9922c2SRobert Mustacchi inttree_inspect(); 407*fa9922c2SRobert Mustacchi nearest_nodes(); 408*fa9922c2SRobert Mustacchi insert_avl(); 409*fa9922c2SRobert Mustacchi inttree_inspect(); 410*fa9922c2SRobert Mustacchi swap_avl(); 411*fa9922c2SRobert Mustacchi cleanup(); 412*fa9922c2SRobert Mustacchi return (0); 413*fa9922c2SRobert Mustacchi} 414*fa9922c2SRobert Mustacchi.Ed 415*fa9922c2SRobert Mustacchi.Sh INTERFACE STABILITY 416*fa9922c2SRobert Mustacchi.Sy Committed 417*fa9922c2SRobert Mustacchi.Sh MT-Level 418*fa9922c2SRobert MustacchiSee 419*fa9922c2SRobert Mustacchi.Sx Locking. 420*fa9922c2SRobert Mustacchi.Sh SEE ALSO 421*fa9922c2SRobert Mustacchi.Xr Intro 3 , 422*fa9922c2SRobert Mustacchi.Xr pthread_atfork 3C 423*fa9922c2SRobert Mustacchi.Lp 424*fa9922c2SRobert Mustacchi.Xr avl_add 3AVL , 425*fa9922c2SRobert Mustacchi.Xr avl_create 3AVL , 426*fa9922c2SRobert Mustacchi.Xr avl_destroy 3AVL , 427*fa9922c2SRobert Mustacchi.Xr avl_destroy_nodes 3AVL , 428*fa9922c2SRobert Mustacchi.Xr avl_find 3AVL , 429*fa9922c2SRobert Mustacchi.Xr avl_first 3AVL , 430*fa9922c2SRobert Mustacchi.Xr avl_insert 3AVL , 431*fa9922c2SRobert Mustacchi.Xr avl_insert_here 3AVL , 432*fa9922c2SRobert Mustacchi.Xr avl_is_empty 3AVL , 433*fa9922c2SRobert Mustacchi.Xr avl_last 3AVL , 434*fa9922c2SRobert Mustacchi.Xr avl_nearest 3AVL , 435*fa9922c2SRobert Mustacchi.Xr avl_numnodes 3AVL , 436*fa9922c2SRobert Mustacchi.Xr avl_remove 3AVL , 437*fa9922c2SRobert Mustacchi.Xr avl_swap 3AVL , 438*fa9922c2SRobert Mustacchi.Rs 439*fa9922c2SRobert Mustacchi.%A Adel'son-Vel'skiy, G. M. 440*fa9922c2SRobert Mustacchi.%A Landis, Ye. M. 441*fa9922c2SRobert Mustacchi.%T "An Algorithm for the Organization of Information" 442*fa9922c2SRobert Mustacchi.%Q Deklady Akademii Nauk 443*fa9922c2SRobert Mustacchi.%C USSR, Moscow 444*fa9922c2SRobert Mustacchi.%P 263-266 445*fa9922c2SRobert Mustacchi.%V Vol. 16 446*fa9922c2SRobert Mustacchi.%N No. 2 447*fa9922c2SRobert Mustacchi.%D 1962 448*fa9922c2SRobert Mustacchi.Re 449