xref: /titanic_54/usr/src/man/man3lib/libavl.3lib (revision fa9922c2be34868be01989cef133828185b5c0bc)
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