Provided by: manpages-es_1.55-10_all 

NOMBRE
tsearch, tfind, tdelete, twalk - manejan un árbol binario
SINOPSIS
#include <search.h>
void *tsearch(const void *key, void **rootp,
int(*compar)(const void *, const void *));
void *tfind(const void *key, const void **rootp,
int(*compar)(const void *, const void *));
void *tdelete(const void *key, void **rootp,
int(*compar)(const void *, const void *));
void twalk(const void *root, void(*action)(const void *nodep,
const VISIT which,
const int depth));
#define _GNU_SOURCE
#include <search.h>
void tdestroy (void *root, void (*free_node)(void *nodep));
DESCRIPCIÓN
tsearch, tfind, twalk y tdelete manejan un árbol binario. Son una generalización del algoritmo T de
Knuth (6.2.2). El primer campo de cada nodo del árbol es un puntero al correspondiente elemento de
datos. (El programa llamante debe almacenar los datos actuales). compar apunta a la rutina de
comparación, que toma punteros a los dos elementos. Debe devolver un entero negativo, cero o positivo
dependiendo de si el primer elemento es menor, igual o mayor que el segundo.
tsearch busca un elemento en el árbol. key apunta al elemento buscado. rootp apunta a la variable que
apunta a la raíz del árbol. Si el árbol está vacío la variable a la que apunta rootp debería estar a
NULL. Si se encuentra el elemento dentro del árbol tsearch devuelve un puntero al elemento. Si no lo
encuentra, tsearch lo añade y devuelve un puntero al nuevo elemento.
tfind es como tsearch, sólo que si no encuentra el elemento tfind devuelve NULL.
tdelete borra un elemento del árbol. Sus argumentos son los mismos que los de tsearch.
twalk realiza un recorrido en profundidad o en anchura de un árbol binario. root apunta al nodo de
comienzo del recorrido. Si el nodo no es la raíz sólo se visitará parte del árbol. twalk llama a la
función de usuario action cada vez que se visita un nodo (esto es, tres veces para un nodo interno y una
vez para una hoja). action, toma tres argumentos. El primero es un puntero al nodo que se está
visitando. El segundo es un entero cuyo valor toma algundo de los valores preorder, postorder o endorder
dependiendo de si esta es la primera, sregunda o tercera visita al nodo interno o leaf si es la única vez
que se visita la hoja. (Estos símbolos están definidos en <search.h>). El tercer argumento es la
profundidad del nodo, siendo la profundidad de la raíz cero.
(Más comúnmente, preorder, postorder, y endorder son conocidos como preorder, inorder, and postorder:
antes de visitar los hijos, después del primero y antes del segundo, y después de visitar los hijos. Así,
la elección del nombre postorder es bastante confusa.)
tdestroy elimina el árbol entero apuntado por rootp, liberando todos los recursos reservados por la
función tsearch. Para los datos en cada nodo del árbol se llama a la función free_node. El puntero a
los datos es pasado como argumento a la función. Si esta tarea no es necesaria free_node debe apuntar a
una función que no haga nada.
VALOR DEVUELTO
tsearch devuelve un puntero al elemento igual del árbol, o al elemento añadido, o NULL si no hubo
suficiente memoria para añadir el elemento. tfind devuelve un puntero al elemento, o NULL si no se
encuentra ninguno igual. Si hay múltiples elementos que concuerdan con la clave el elemento devuelto es
inespecificado.
tdelete devuelve un puntero al padre del elemento borrado, o NULL si no se encontró el elemento.
tsearch, tfind, y tdelete devuelven NULL si rootp es NULL en la entrada a la función.
ADVERTENCIAS
twalk toma un puntero a la raíz, mientra que las otras funciones toman un puntero a una variable que
apunta a la raíz.
twalk usa postorder con el significado "depués del subárbol izquierdo y antes del subárbol derecho".
Algunas autoridades llamana a esto "inorden" y reservan "postorden" con el significado "después de ambos
subárboles".
tdelete libera la memoria necesaria para el elemento en el árbol. El usuario es el responsable de
liberar la memoria de los correspondientes datos.
El programa de ejemplo depende del hecho de que twalk no vuelve a referenciar a un nodo después de llamar
a la función de usuario con el argumento "endorder" o "leaf". Esto funciona con la biblioteca de GNU,
pero no está en la documentación SysV.
EJEMPLO
El ejemplo siguiente inserta doce números aleatorios en un árbol binario, donde los números duplicados se
meten hacia abajo, e imprime los números en orden.
#include <search.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
void *root=NULL;
void *xmalloc(unsigned n) {
void *p;
p = malloc(n);
if(p) return p;
fprintf(stderr, "insufficient memory\n");
exit(1);
}
int compare(const void *pa, const void *pb) {
if(*(int *)pa < *(int *)pb) return -1;
if(*(int *)pa > *(int *)pb) return 1;
return 0;
}
void action(const void *nodep, const VISIT which, const int depth) {
int *datap;
switch(which) {
case preorder:
break;
case postorder:
datap = *(int **)nodep;
printf("%6d\n", *datap);
break;
case endorder:
break;
case leaf:
datap = *(int **)nodep;
printf("%6d\n", *datap);
break;
}
}
int main() {
int i, *ptr;
void *val;
srand(time(NULL));
for (i = 0; i < 12; i++) {
ptr = (int *)xmalloc(sizeof(int));
*ptr = rand()&0xff;
val = tsearch((void *)ptr, &root, compare);
if(val == NULL) exit(1);
}
twalk(root, action);
return 0;
}
CONFORME A
SVID. La función tdestroy() es una extensión de GNU.
VÉASE TAMBIÉN
qsort(3), bsearch(3), hsearch(3), lsearch(3)
GNU 24 septiembre 1995 TSEARCH(3)