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

📄 eavlmmap.h

📁 大型并行量子化学软件;支持密度泛函(DFT)。可以进行各种量子化学计算。支持CHARMM并行计算。非常具有应用价值。
💻 H
📖 第 1 页 / 共 2 页
字号:
//// eavlmmap.h --- definition for embedded avl multimap class//// Copyright (C) 1996 Limit Point Systems, Inc.//// Author: Curtis Janssen <cljanss@limitpt.com>// Maintainer: LPS//// This file is part of the SC Toolkit.//// The SC Toolkit is free software; you can redistribute it and/or modify// it under the terms of the GNU Library General Public License as published by// the Free Software Foundation; either version 2, or (at your option)// any later version.//// The SC Toolkit 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 Library General Public License for more details.//// You should have received a copy of the GNU Library General Public License// along with the SC Toolkit; see the file COPYING.LIB.  If not, write to// the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.//// The U.S. Government is granted a limited license as per AL 91-7.//#ifndef _util_container_eavlmmap_h#define _util_container_eavlmmap_h#ifdef HAVE_CONFIG_H#  include <scconfig.h>#endif#include <iostream>#include <util/misc/exenv.h>#include <util/container/compare.h>#include <unistd.h> // for size_t on solaris#include <stdlib.h>#ifdef __GNUC__// gcc typename seems to be broken in some cases#  define eavl_typename#else#  define eavl_typename typename#endifnamespace sc {template <class K, class T>class EAVLMMapNode {  public:    K key;    T* lt;    T* rt;    T* up;    int balance;  public:    EAVLMMapNode(const K& k): key(k) {}};template <class K, class T>class EAVLMMap {  private:    size_t length_;    T *root_;    T *start_;    EAVLMMapNode<K,T> T::* node_;  public:    T*& rlink(T* n) const { return (n->*node_).rt; }    T* rlink(const T* n) const { return (n->*node_).rt; }    T*& llink(T* n) const { return (n->*node_).lt; }    T* llink(const T* n) const { return (n->*node_).lt; }    T*& uplink(T* n) const { return (n->*node_).up; }    T* uplink(const T* n) const { return (n->*node_).up; }    int& balance(T* n) const { return (n->*node_).balance; }    int balance(const T* n) const { return (n->*node_).balance; }    K& key(T* n) const { return (n->*node_).key; }    const K& key(const T* n) const { return (n->*node_).key; }    int compare(T*n,T*m) const { return sc::compare(key(n), key(m)); }    int compare(T*n,const K&m) const { return sc::compare(key(n), m); }  private:    void adjust_balance_insert(T* A, T* child);    void adjust_balance_remove(T* A, T* child);    void clear(T*);  public:    class iterator {      private:        EAVLMMap<K,T> *map_;        T *node;      public:        iterator(EAVLMMap<K,T> *m, T *n):map_(m),node(n){}        iterator(const eavl_typename EAVLMMap<K,T>::iterator &i) { map_=i.map_; node=i.node; }        void operator++() { map_->next(node); }        void operator++(int) { operator++(); }        int operator == (const eavl_typename EAVLMMap<K,T>::iterator &i) const            { return map_ == i.map_ && node == i.node; }        int operator != (const eavl_typename EAVLMMap<K,T>::iterator &i) const            { return !operator == (i); }        void operator = (const eavl_typename EAVLMMap<K,T>::iterator &i)            { map_ = i.map_; node = i.node; }        const K &key() const { return map_->key(node); }        T & operator *() { return *node; }        T * operator->() { return node; }    };  public:    EAVLMMap();    EAVLMMap(EAVLMMapNode<K,T> T::* node);    ~EAVLMMap() { clear(root_); }    void initialize(EAVLMMapNode<K,T> T::* node);    void clear_without_delete() { initialize(node_); }    void clear() { clear(root_); initialize(node_); }    void insert(T*);    void remove(T*);    T* find(const K&) const;    int height(T* node);    int height() { return height(root_); }    void check();    void check_node(T*) const;    T* start() const { return start_; }    void next(const T*&) const;    void next(T*&) const;    iterator begin() { return iterator(this,start()); }    iterator end() { return iterator(this,0); }    void print();    int length() const { return length_; }    int depth(T*);};template <class K, class T>T*EAVLMMap<K,T>::find(const K& key) const{  T* n = root_;  while (n) {      int cmp = compare(n, key);      if (cmp < 0) n = rlink(n);      else if (cmp > 0) n = llink(n);      else return n;    }  return 0;}template <class K, class T>voidEAVLMMap<K,T>::remove(T* node){  if (!node) return;  length_--;  if (node == start_) {      next(start_);    }  T *rebalance_point;  T *q;  if (llink(node) == 0) {      q = rlink(node);      rebalance_point = uplink(node);      if (q) uplink(q) = rebalance_point;      if (rebalance_point) {          if (rlink(rebalance_point) == node) rlink(rebalance_point) = q;          else llink(rebalance_point) = q;        }      else root_ = q;    }  else if (rlink(node) == 0) {      q = llink(node);      rebalance_point = uplink(node);      if (q) uplink(q) = rebalance_point;      if (rebalance_point) {          if (rlink(rebalance_point) == node) rlink(rebalance_point) = q;          else llink(rebalance_point) = q;        }      else root_ = q;    }  else {      T *r = node;      next(r);      if (r == 0 || llink(r) != 0) {          ExEnv::errn() << "EAVLMMap::remove: inconsistency" << std::endl;          abort();        }      if (r == rlink(node)) {          llink(r) = llink(node);          if (llink(r)) uplink(llink(r)) = r;          balance(r) = balance(node);          rebalance_point = r;          q = rlink(r);        }      else {          q = rlink(r);          rebalance_point = uplink(r);          if (llink(rebalance_point) == r) llink(rebalance_point) = q;          else rlink(rebalance_point) = q;          if (q) uplink(q) = rebalance_point;          balance(r) = balance(node);          rlink(r) = rlink(node);          llink(r) = llink(node);          if (rlink(r)) uplink(rlink(r)) = r;          if (llink(r)) uplink(llink(r)) = r;        }      if (r) {          T* up = uplink(node);          uplink(r) = up;          if (up) {              if (rlink(up) == node) rlink(up) = r;              else llink(up) = r;            }          if (up == 0) root_ = r;        }    }  // adjust balance won't work if both children are null,  // so handle this special case here  if (rebalance_point &&      llink(rebalance_point) == 0 && rlink(rebalance_point) == 0) {      balance(rebalance_point) = 0;      q = rebalance_point;      rebalance_point = uplink(rebalance_point);    }  adjust_balance_remove(rebalance_point, q);}template <class K, class T>voidEAVLMMap<K,T>::print(){  for (T*n=start(); n; next(n)) {      int d = depth(n) + 1;      for (int i=0; i<d; i++) ExEnv::out0() << "     ";      if (balance(n) == 1) ExEnv::out0() << " (+)" << std::endl;      else if (balance(n) == -1) ExEnv::out0() << " (-)" << std::endl;      else if (balance(n) == 0) ExEnv::out0() << " (.)" << std::endl;      else ExEnv::out0() << " (" << balance(n) << ")" << std::endl;    }}template <class K, class T>intEAVLMMap<K,T>::depth(T*node){  int d = 0;  while (node) {      node = uplink(node);      d++;    }  return d;}template <class K, class T>voidEAVLMMap<K,T>::check_node(T*n) const{  if (uplink(n) && uplink(n) == n) abort();  if (llink(n) && llink(n) == n) abort();  if (rlink(n) && rlink(n) == n) abort();  if (rlink(n) && rlink(n) == llink(n)) abort();  if (uplink(n) && uplink(n) == llink(n)) abort();  if (uplink(n) && uplink(n) == rlink(n)) abort();  if (uplink(n) && !(llink(uplink(n)) == n                     || rlink(uplink(n)) == n)) abort();}template <class K, class T>voidEAVLMMap<K,T>::clear(T*n){  if (!n) return;  clear(llink(n));  clear(rlink(n));  delete n;}template <class K, class T>intEAVLMMap<K,T>::height(T* node){  if (!node) return 0;  int rh = height(rlink(node)) + 1;  int lh = height(llink(node)) + 1;  return rh>lh?rh:lh;}template <class K, class T>voidEAVLMMap<K,T>::check(){  T* node;  T* prev=0;  size_t computed_length = 0;  for (node = start(); node; next(node)) {      check_node(node);      if (prev && compare(prev,node) > 0) {          ExEnv::errn() << "nodes out of order" << std::endl;          abort();        }      prev = node;      computed_length++;    }  for (node = start(); node; next(node)) {      if (balance(node) != height(rlink(node)) - height(llink(node))) {          ExEnv::errn() << "balance inconsistency" << std::endl;          abort();        }      if (balance(node) < -1 || balance(node) > 1) {          ExEnv::errn() << "balance out of range" << std::endl;          abort();        }    }  if (length_ != computed_length) {      ExEnv::errn() << "length error" << std::endl;      abort();    }}template <class K, class T>voidEAVLMMap<K,T>::next(const T*& node) const{  const T* r;  if (r = rlink(node)) {      node = r;      while (r = llink(node)) node = r;      return;    }  while (r = uplink(node)) {      if (node == llink(r)) {          node = r;          return;        }      node = r;    }  node = 0;}template <class K, class T>voidEAVLMMap<K,T>::next(T*& node) const{  T* r;  if (r = rlink(node)) {      node = r;      while (r = llink(node)) node = r;      return;    }

⌨️ 快捷键说明

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