home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #20 / NN_1992_20.iso / spool / comp / lang / cplus / 13397 < prev    next >
Encoding:
Text File  |  1992-09-08  |  5.5 KB  |  157 lines

  1. Newsgroups: comp.lang.c++
  2. Path: sparky!uunet!news.claremont.edu!ucivax!ucla-cs!ucla-mic!agsm!iwelch
  3. From: iwelch@agsm.ucla.edu (Ivo Welch)
  4. Subject: General Datastructure Design Question
  5. Message-ID: <1992Sep8.114516.4105@mic.ucla.edu>
  6. Nntp-Posting-Host: risc.agsm.ucla.edu
  7. Organization: UCLA, Anderson Graduate School Of Management
  8. Date: 8 Sep 92 11:45:16 PDT
  9. Lines: 146
  10.  
  11.  
  12. I am rather proficient in C, but a complete novice to C++--which is driving me
  13. up the wall. I am running gcc-1.93 (68K, as ported by NeXT 3.0PR2), which does
  14. not offer templates. I cannot upgrade to gcc 2.2, because gdb is not ported to
  15. NeXT. I have a beginner's design problem:
  16.  
  17.  
  18. I am trying to define a simple data structure,  like a binary  tree, which can
  19. be used by any other data structures. So, I decided to  go the C++ way, rather
  20. than passing byte sizes of structures as I would in C.
  21.  
  22. My guess was that a good  design would  define an abstract "TreeNode" class on
  23. which  my   BinaryTree  class would  operate.    This  abstract TreeNode class
  24. declares 2 functions, (fix, compare).   A user would   define  her own  "Node"
  25. class, inheriting the abstract  class,  which  [a] contains the data   and [b]
  26. defines the fix() [=copy] and compare() functions.  The instantiated user-node
  27. object carries with   it the information  of  what compare  and  fix functions
  28. operate on it, because it is derived from a virtual abstract class.
  29.  
  30. Beautiful. Except that I cannot get the damn thing to  work.  Run-time errors.
  31. The old gdb debugger 3.95 is less than helpful.  Could someone  please send me
  32. an example of an implementation  that does something like this.  I do not want
  33. to bother people with my code, but perhaps it clarifies some of my problems.
  34.  
  35. /ivo
  36.  
  37.  
  38. The following code carries around some additional printing code, as well as an
  39. ugly mixture of malloc's and new's, as well as some other bad C habits.
  40.  
  41. /****************************************************************/
  42. extern "C" {
  43. #include <stdio.h>
  44. #include <stdlib.h>
  45. #include <string.h>
  46. }
  47.  
  48. #include "BinaryTree.h"
  49.  
  50. class Node : public TreeNode {
  51.   char *key;
  52.   int value;
  53.  public:
  54.   Node(char *key, int value) { this->key= strcpy(malloc(strlen(key+1)+1), key); this->value= value; }
  55.   Node() { this->key= 0; this->value= (-1); }
  56.   ~Node() { if (key!=0) free(key); key= 0; }
  57.  
  58.   // now override the abstract definition;
  59.   TreeNode *fix(TreeNode *source_virtual) {
  60.     Node *dest; Node *src = (Node *) source_virtual;
  61.     fprintf(stderr, "[Fixing]\n");
  62.     dest= malloc(sizeof(Node)+1);
  63.     dest->key= strcpy(malloc(strlen(src->key)+1), src->key);
  64.     dest->value= src->value;
  65.     fprintf(stderr, "[Fixed]\n");
  66.     return dest;
  67.   }
  68.   int compare(TreeNode *other) { return strcmp(this->key, ((Node *) other)->key); };
  69.   void print(FILE *f =stdout) { fprintf(f, "Node [%s] = %d\n", key, value); };
  70. } ;
  71.  
  72. /****************************************************************/
  73. int main() {
  74.   BinaryTree b;
  75.   b.setdebug(1);
  76.  
  77.   { Node store1("first", 1);    b.insert(&store1);  }
  78.   { Node store2("second", 2);    b.insert(&store2); }
  79.   { Node store3("third", 3);    b.insert(&store3); }
  80.   { Node store4("fourth", 4);    b.insert(&store4); }
  81.   { Node store5("fifth", 5);    b.insert(&store5); }
  82.   { Node store6("six", 6);    b.insert(&store6); }
  83.  
  84.   b.print();  printf("\n");  b.printinternal();
  85.   return 0;
  86. }
  87.  
  88.  
  89. Here comes my BinaryTree class, and the abstract TreeNode class.
  90.  
  91. /****************************************************************/
  92. // abstract class
  93. class TreeNode {
  94.  public:
  95.   virtual TreeNode *fix(TreeNode *src) =0;
  96.   virtual int compare(TreeNode *other) =0;
  97.   virtual void print(FILE *f =stdout) =0;
  98. } ;
  99.  
  100.  
  101. // the data structure operating on objects carrying the
  102. // fix(), compare() and print() functions with them.
  103. class BinaryTree {
  104.   struct BinaryTreeNode {
  105.     BinaryTreeNode *left, *right;
  106.     TreeNode *value;
  107.   public:
  108.     BinaryTreeNode(TreeNode *newnode) { left=right= 0; value= newnode->fix(newnode); }
  109.     void print(FILE *f =stdout);
  110.     void printinternal(FILE *f =stdout);
  111.  
  112.     ~BinaryTreeNode() { right=right=0; } // I hope that value here gets deallocated;
  113.   };
  114.   BinaryTreeNode *root;
  115.   int debug;
  116.  
  117.  public:
  118.   BinaryTree() { root = 0; debug = 0; } ;
  119.   ~BinaryTree() { };
  120.   void print(FILE *f =stdout) { root->print(f); }
  121.   void printinternal(FILE *f =stdout) { root->printinternal(f); }
  122.   void setdebug(int i) { debug= i; }
  123.  
  124.   // each node has its own size;
  125.   TreeNode *insert(TreeNode *newvalue) {
  126.     BinaryTreeNode **cur= &root;
  127.     if (debug) fprintf(stderr, "Entering Insert\n");
  128.     while (*cur) {
  129.       if (debug) { fprintf(stderr, "Comparing old value :"); (*cur)->value->print(); }
  130.       if (debug) { fprintf(stderr, "To new value :"); newvalue->print(); }
  131.  
  132.       int result= (-1)*newvalue->compare((*cur)->value);
  133.       if (result==0) { return (*cur)->value; } // found; already exists!;
  134.       else if (result<0) cur= &((*cur)->left);
  135.       else cur= &((*cur)->right);
  136.     }
  137.     if (debug) fprintf(stderr, "Malloc\n");
  138.     (*cur) = new BinaryTreeNode(newvalue); // allocate space and call constructor;
  139.     if (debug) fprintf(stderr, "Exiting Insert\n");
  140.     return newvalue;
  141.   }
  142. } ;
  143.  
  144. // recursive functions;
  145. void BinaryTreeNode::print(FILE *f =stdout) {
  146.   if (right!=0) right->print();
  147.   value->print(f);
  148.   if (left!=0) left->print();
  149. }
  150.  
  151. void BinaryTreeNode::printinternal(FILE *f =stdout) {
  152.   static int level= 0; 
  153.   int c; for (c=0; c<level; ++c) putc(' ',f); value->print(f);
  154.   if (left!=0) { level+=4;  putc('L', f); left->printinternal(); level-=4; }
  155.   if (right!=0) { level+=4; putc('R', f); right->printinternal(); level-=4; }
  156. }
  157.