#include<iostream.h>
#include<string.h>
#include<assert.h>

template<class Data> struct ANode {
  char *index;
  Data d;
  ANode *left, *right;
  ~ANode() {
    delete left;
    index=NULL;
    delete right;
  };
  ANode(const ANode &other) {
    index=new char[strlen(other.index)];
    strcpy(index, other.index);
    d=other.d;
    left=right=0;
  };
  ANode() : index(0), right(NULL), left(NULL) {;};
  friend ostream& operator<<(ostream& ost, const ANode& node) {
    return(ost << node.index << ": " << node.d << endl);
  };
  friend ostream& operator<<(ostream& ost, const ANode* &pnode) {
    if (pnode) {
      ost << (const ANode*)pnode->left;
      ost << (*pnode);
      ost << endl;
      ost << (const ANode*)pnode->right;
    }
    return(ost);
  };
};


template<class Data> class Aarray {
private:
  void insert(ANode<Data> *);
public:
  ANode<Data> *root;
  unsigned int nodes;
public:
  Aarray();
  Aarray(const Data&, const char*);
  Aarray(const Aarray&);
  ~Aarray();
  Aarray& operator=(const Aarray&);
  unsigned int elem(const char*);
  Data& operator[](char*);
  Data remove(const char*);
  Data remove(const char*, ANode<Data>* &);
  friend Aarray& operator+=(Aarray&, const Aarray&);
  operator int() { return(nodes); }
  friend Aarray operator+(Aarray&, const Aarray&);
  //   friend istream& operator>>(istream&, const Aarray&);
  friend ostream& operator<<(ostream&, const Aarray&);
  ANode<Data>* find_min(ANode<Data> *);
  void copytree(ANode<Data>*&, ANode<Data> *);
  void merge(ANode<Data>* source) {
    if (source) {
      merge(source->left);
      insert(source);
      merge(source->right);
    };
  };
};
