home *** CD-ROM | disk | FTP | other *** search
- // This may look like C code, but it is really -*- C++ -*-
- /*
- Copyright (C) 1988 Free Software Foundation
- written by Doug Lea (dl@rocky.oswego.edu)
-
- This file is part of GNU CC.
-
- GNU CC is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY. No author or distributor
- accepts responsibility to anyone for the consequences of using it
- or for whether it serves any particular purpose or works at all,
- unless he says so in writing. Refer to the GNU CC General Public
- License for full details.
-
- Everyone is granted permission to copy, modify and redistribute
- GNU CC, but only under the conditions described in the
- GNU CC General Public License. A copy of this license is
- supposed to have been given to you along with GNU CC so you
- can know your rights and responsibilities. It should be in a
- file named COPYING. Among other things, the copyright notice
- and this notice must be preserved on all copies.
- */
-
- #include <stream.h>
- #include "<T><U>BSTAssoc.h"
-
- // error handling
-
-
- void default_<T><U>BSTAssoc_error_handler(char* msg)
- {
- cerr << "Fatal <T><U>BSTAssoc error. " << msg << "\n";
- exit(1);
- }
-
- one_arg_error_handler_t <T><U>BSTAssoc_error_handler = default_<T><U>BSTAssoc_error_handler;
-
- one_arg_error_handler_t set_<T><U>BSTAssoc_error_handler(one_arg_error_handler_t f)
- {
- one_arg_error_handler_t old = <T><U>BSTAssoc_error_handler;
- <T><U>BSTAssoc_error_handler = f;
- return old;
- }
-
- void <T><U>BSTAssoc::error(const char* msg)
- {
- (*<T><U>BSTAssoc_error_handler)(msg);
- }
-
-
- int <T><U>BSTAssoc::contains(<T&> key)
- {
- <T><U>BSTAssocNode* t = root;
- for (;;)
- {
- if (t == 0)
- return 0;
- int comp = key_key_cmp(t->key, key);
- if (comp == 0)
- return 1;
- else if (comp > 0)
- t = t->lt;
- else
- t = t->rt;
- }
- }
-
- <U>& <T><U>BSTAssoc::operator[](<T&> key)
- {
- if (root == 0)
- {
- ++cnt;
- root = new <T><U>BSTAssocNode(key);
- return root->cont;
- }
-
- <T><U>BSTAssocNode* t = root;
- <T><U>BSTAssocNode* p = root;
- int comp;
- for (;;)
- {
- if (t == 0)
- {
- ++cnt;
- t = new <T><U>BSTAssocNode(key);
- if (comp > 0)
- p->lt = t;
- else
- p->rt = t;
- return t->cont;
- }
- p = t;
- comp = key_key_cmp(t->key, key);
- if (comp == 0)
- return t->cont;
- else if (comp > 0)
- t = t->lt;
- else
- t = t->rt;
- }
- }
-
-
- int <T><U>BSTAssoc::del(<T&> key)
- {
- <T><U>BSTAssocNode* t = root;
- <T><U>BSTAssocNode* p = root;
- for (;;)
- {
- if (t == 0)
- return 0;
- int comp = key_key_cmp(t->key, key);
- if (comp == 0)
- {
- --cnt;
- <T><U>BSTAssocNode* repl;
- if (t->lt == 0)
- repl = t->rt;
- else if (t->rt == 0)
- repl = t->lt;
- else
- {
- <T><U>BSTAssocNode* prepl = t;
- repl = t->lt;
- while (repl->rt != 0)
- {
- prepl = repl;
- repl = repl->rt;
- }
- if (prepl != t)
- {
- prepl->rt = repl->lt;
- repl->lt = t->lt;
- }
- repl->rt = t->rt;
- }
- if (t == root)
- root = repl;
- else if (t == p->lt)
- p->lt = repl;
- else
- p->rt = repl;
- return 1;
- }
- p = t;
- if (comp > 0)
- t = t->lt;
- else
- t = t->rt;
- }
- }
-
-
- void <T><U>BSTAssoc::_kill(<T><U>BSTAssocNode* t)
- {
- if (t != 0)
- {
- _kill(t->lt);
- _kill(t->rt);
- delete t;
- }
- }
-
- void <T><U>BSTAssoc::_apply(<U>Procedure f, <T><U>BSTAssocNode* t)
- {
- if (t != 0)
- {
- _apply(f, t->lt);
- (*f)(t->cont);
- _apply(f, t->rt);
- }
- }
-
- <T><U>BSTAssocNode* <T><U>BSTAssoc::_copy(<T><U>BSTAssocNode* t)
- {
- if (t == 0)
- return 0;
- else
- return new <T><U>BSTAssocNode(t->key, t->cont, _copy(t->lt), _copy(t->rt));
- }
-
- static <T><U>BSTAssocNode* _BSTbal(<T><U>BSTAssocNode** a, int lo, int hi)
- {
- if (lo > hi)
- return 0;
- else if (lo == hi)
- {
- a[lo]->lt = a[lo]->rt = 0;
- return a[lo];
- }
- else
- {
- int mid = (lo + hi) / 2;
- a[mid]->lt = _BSTbal(a, lo, mid-1);
- a[mid]->rt = _BSTbal(a, mid+1, hi);
- return a[mid];
- }
- }
-
- static int _BSTfill(<T><U>BSTAssocNode** a, int pos, <T><U>BSTAssocNode* t)
- {
- if (t == 0)
- return pos;
- else
- {
- int p = _BSTfill(a, pos, t->lt);
- a[p++] = t;
- return _BSTfill(a, p, t->rt);
- }
- }
-
- void <T><U>BSTAssoc::balance()
- {
- if (root != 0)
- {
- <T><U>BSTAssocNode** a = new <T><U>BSTAssocNodePtr [cnt];
- _BSTfill(a, 0, root);
- root = _BSTbal(a, 0, cnt-1);
- delete a;
- }
- }
-
-
-
- void <T><U>BSTAssocTrav::reset()
- {
- if (stk != 0)
- delete stk;
- stk = new <T><U>BSTAssocNodePtr[h->cnt];
- sp = -1;
- <T><U>BSTAssocNode* p = h->root;
- while (p != 0)
- {
- stk[++sp] = p;
- p = p->lt;
- }
- }
-
-
- void <T><U>BSTAssocTrav::advance()
- {
- if (sp >= 0)
- {
- <T><U>BSTAssocNode* p = stk[sp--]->rt;
- while (p != 0)
- {
- stk[++sp] = p;
- p = p->lt;
- }
- }
- }
-
-
-
-