⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gdsl_bstree.c

📁 一个通用的C语言实现的数据结构
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * This file is part of the Generic Data Structures Library (GDSL). * Copyright (C) 1998-2006 Nicolas Darnis <ndarnis@free.fr>. * * The GDSL library is free software; you can redistribute it and/or  * modify it under the terms of the GNU General Public License as  * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * The GDSL library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with the GDSL library; see the file COPYING. * If not, write to the Free Software Foundation, Inc.,  * 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA. * * $RCSfile: gdsl_bstree.c,v $ * $Revision: 1.24 $ * $Date: 2006/03/04 16:32:05 $ */#include <config.h>#include <stdlib.h>#include <string.h>#include <assert.h>#include "gdsl_types.h"#include "_gdsl_bintree.h"#include "gdsl_bstree.h"#define LEFT(t)       ( _gdsl_bintree_get_left ((t)) )#define RIGHT(t)      ( _gdsl_bintree_get_right ((t)) )#define CONTENT(t)    ( _gdsl_bintree_get_content ((t)) )#define PARENT(t)     ( _gdsl_bintree_get_parent ((t)) )#define SENT(t)       ( (t)->sent )#define ROOT(t)       ( _gdsl_bintree_get_right (SENT (t)) )struct gdsl_bstree{    char*               name;    /* tree's name */    ulong               card;    /* tree's cardinality */    _gdsl_bintree_t     sent;    /* tree's sentinel */    gdsl_alloc_func_t   alloc_f; /* */    gdsl_free_func_t    free_f;  /* */    gdsl_compare_func_t comp_f;  /* */};static gdsl_element_t default_alloc (void* e);static void default_free (gdsl_element_t e);static long int default_comp (gdsl_element_t e, void* key);static void bstree_free (_gdsl_bintree_t n, _gdsl_bintree_t sent, gdsl_free_func_t f);static ulongbstree_height (_gdsl_bintree_t n, _gdsl_bintree_t sent);static _gdsl_bintree_tbstree_search (_gdsl_bintree_t n, _gdsl_bintree_t sent, gdsl_compare_func_t f,	       void* v );static _gdsl_bintree_tbstree_next (gdsl_bstree_t t, _gdsl_bintree_t n);static gdsl_element_tbstree_prefix_parse (_gdsl_bintree_t t, _gdsl_bintree_t sent, gdsl_map_func_t f, 		     void* d);static gdsl_element_tbstree_infix_parse (_gdsl_bintree_t t, _gdsl_bintree_t sent, gdsl_map_func_t f, 		    void* d);static gdsl_element_tbstree_postfix_parse (_gdsl_bintree_t t, _gdsl_bintree_t sent, gdsl_map_func_t f, 		      void* d);static voidbstree_write (_gdsl_bintree_t n, _gdsl_bintree_t sent, gdsl_write_func_t f,	      FILE* file, void* d);static voidbstree_write_xml (_gdsl_bintree_t n, _gdsl_bintree_t sent, 		  gdsl_write_func_t f, FILE* file, void* d);static voidbstree_dump (_gdsl_bintree_t n, _gdsl_bintree_t sent, gdsl_write_func_t f, 	     FILE* file, void* d);static gdsl_location_tget_location (_gdsl_bintree_t t, _gdsl_bintree_t n);/******************************************************************************//* Management functions of binary search trees                                *//******************************************************************************/extern gdsl_bstree_tgdsl_bstree_alloc (const char* name, const gdsl_alloc_func_t alloc_f, 		   gdsl_free_func_t free_f, gdsl_compare_func_t comp_f){    gdsl_bstree_t t;    t = (gdsl_bstree_t) malloc (sizeof (struct gdsl_bstree));    if (t == NULL)	{	    return NULL;	}    t->sent = _gdsl_bintree_alloc (NULL, NULL, NULL);    if (t->sent == NULL)	{	    free (t);	    return NULL;	}    _gdsl_bintree_set_parent ((_gdsl_bintree_t) (t->sent), (_gdsl_bintree_t) (t->sent));    _gdsl_bintree_set_left ((_gdsl_bintree_t) (t->sent), (_gdsl_bintree_t) (t->sent));    _gdsl_bintree_set_right ((_gdsl_bintree_t) (t->sent), (_gdsl_bintree_t) (t->sent));    t->name = NULL;    if (gdsl_bstree_set_name (t, name) == NULL)	{	    free (t);	    return NULL;	}    t->comp_f  = comp_f  ? comp_f  : default_comp;    t->alloc_f = alloc_f ? alloc_f : default_alloc;    t->free_f  = free_f  ? free_f  : default_free;    t->card = 0UL;    return t;}extern voidgdsl_bstree_free (gdsl_bstree_t t){    assert (t != NULL);    bstree_free (ROOT (t), SENT (t), t->free_f);    /*     * NOTE:     * As SENT(t) is allocated, we must deallocate it, so we set     * its left and right sons to NULL to avoid infinite recursion:     */    _gdsl_bintree_set_left ((_gdsl_bintree_t) SENT (t), NULL);    _gdsl_bintree_set_right ((_gdsl_bintree_t) SENT (t), NULL);    _gdsl_bintree_free (SENT (t), NULL);    if (t->name != NULL)	{	    free (t->name);	}    free (t);}extern voidgdsl_bstree_flush (gdsl_bstree_t t){    assert (t != NULL);    bstree_free (ROOT (t), SENT (t), t->free_f);    _gdsl_bintree_set_left ((_gdsl_bintree_t) SENT (t), (_gdsl_bintree_t) SENT (t));    _gdsl_bintree_set_right ((_gdsl_bintree_t) SENT (t), (_gdsl_bintree_t) SENT (t));    t->card = 0UL;}#if 0extern gdsl_bstree_tgdsl_bstree_copy (const gdsl_bstree_t t){    /* !! TO DO... !! */    return NULL;}#endif/******************************************************************************//* Consultation functions of binary search trees                              *//******************************************************************************/extern const char*gdsl_bstree_get_name (const gdsl_bstree_t t){    assert (t != NULL);    return t->name;}extern boolgdsl_bstree_is_empty (const gdsl_bstree_t t){    assert (t != NULL);    return (bool) (t->card == 0); /* alt. ROOT( t ) == SENT( t ) */}extern gdsl_element_tgdsl_bstree_get_root (const gdsl_bstree_t t){    assert (t != NULL);    return CONTENT (ROOT (t));}extern ulonggdsl_bstree_get_size (const gdsl_bstree_t t){    assert (t != NULL);    return t->card;}extern ulonggdsl_bstree_get_height (const gdsl_bstree_t t){    assert (t != NULL);    return bstree_height (ROOT (t), SENT (t));}/******************************************************************************//* Modification functions of binary search trees                              *//******************************************************************************/extern gdsl_bstree_tgdsl_bstree_set_name (gdsl_bstree_t t, const char* name){    assert (t != NULL);    if (t->name != NULL)	{	    free (t->name);	    t->name = NULL;	}    if (name != NULL)	{	    t->name = (char*) malloc ((1 + strlen (name)) * sizeof (char));	    if (t->name == NULL)		{		    return NULL;		}	    strcpy (t->name, name);	}    return t;}extern gdsl_element_tgdsl_bstree_insert (gdsl_bstree_t t, void* v, int* rc){    int             comp = 0;    gdsl_element_t  e;    _gdsl_bintree_t root;    _gdsl_bintree_t parent;    _gdsl_bintree_t n;    assert (t != NULL);    assert (rc != NULL);    *rc = GDSL_INSERTED;    /* Classic binary search tree insertion */    root = ROOT (t);    parent = SENT (t);    while (root != SENT (t))	{	    parent = root;	    comp = t->comp_f (CONTENT (root), v);	    /* Found v */	    if (comp == 0)		{		    *rc = GDSL_FOUND;		    return CONTENT (root);		}	    root = (comp > 0) ? LEFT (root) : RIGHT (root); 	}    /* Then, we create the new node n and we insert it into t */    e = (t->alloc_f) (v);    if (e == NULL)	{	    *rc = GDSL_ERR_MEM_ALLOC;	    return NULL;	}    n = _gdsl_bintree_alloc (e, NULL, NULL);    if (n == NULL)	{	    t->free_f (e);	    *rc = GDSL_ERR_MEM_ALLOC;	    return NULL;	}    /* Insertion of n into t */    _gdsl_bintree_set_parent ((_gdsl_bintree_t) n, (_gdsl_bintree_t) parent);    _gdsl_bintree_set_left ((_gdsl_bintree_t) n, (_gdsl_bintree_t) SENT (t));    _gdsl_bintree_set_right ((_gdsl_bintree_t) n, (_gdsl_bintree_t) SENT (t));      if (parent == SENT(t) || comp < 0)	{	    _gdsl_bintree_set_right ((_gdsl_bintree_t) parent, (_gdsl_bintree_t) n);	}    else	{	    _gdsl_bintree_set_left ((_gdsl_bintree_t) parent, (_gdsl_bintree_t) n);	}    t->card++;    return e;}extern gdsl_element_tgdsl_bstree_remove (gdsl_bstree_t t, void* v){    gdsl_element_t e;    _gdsl_bintree_t n;    _gdsl_bintree_t child;    assert (t != NULL);    /* First we search into t for a node n containing v: */    n = bstree_search (ROOT (t), SENT (t), t->comp_f, v);    if (n == NULL)	{	    return NULL;	}    /* Then, we do a classical removing of node n from a binary search tree t: */    if (LEFT (n) != SENT (t) && RIGHT (n) != SENT (t))	{	    _gdsl_bintree_t next = bstree_next (t, n);	    _gdsl_bintree_t nextparent = PARENT (next);	    child = RIGHT (next);	    _gdsl_bintree_set_parent (child, nextparent);	    if (LEFT (nextparent) == next)		{		    _gdsl_bintree_set_left (nextparent, child);		}	    else		{		    _gdsl_bintree_set_right (nextparent, child);		}	    _gdsl_bintree_set_parent (next, PARENT (n));	    _gdsl_bintree_set_left (next, LEFT (n));	    _gdsl_bintree_set_right (next, RIGHT (n));	    _gdsl_bintree_set_parent (LEFT (next), next);	    _gdsl_bintree_set_parent (RIGHT (next), next);      	    if (LEFT (PARENT (n)) == n)		{		    _gdsl_bintree_set_left (PARENT (n), next);		}	    else		{		    _gdsl_bintree_set_right (PARENT (n), next);		}	}    else	{	    child = LEFT (n) != SENT (t) ? LEFT (n) : RIGHT (n);	    _gdsl_bintree_set_parent (child, PARENT (n));	    if (n == LEFT (PARENT (n)))		{		    _gdsl_bintree_set_left (PARENT (n), child);		}	    else		{		    _gdsl_bintree_set_right (PARENT (n), child);		}	}    t->card--;    e = CONTENT (n);    _gdsl_bintree_set_left ((_gdsl_bintree_t) n, NULL);    _gdsl_bintree_set_right ((_gdsl_bintree_t) n, NULL);    _gdsl_bintree_free (n, NULL);    return e;}extern gdsl_bstree_tgdsl_bstree_delete (gdsl_bstree_t t, void* v){    gdsl_element_t e;    assert (t != NULL);    e = gdsl_bstree_remove (t, v);    if (e == NULL)	{	    return NULL;	}    t->free_f (e);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -