CSCI 161: Spring 2022 Final Exam
Sections F22N03-F22N06 (Dr. Wessels)


Q1: Searching/sorting:
An algorithm for a new sorting function is provided below.
(i) Provide an implementation of the function, following the algorithm as closely as possible.
(ii) Explain what the worst case order of efficiency is for this algorithm (e.g. O(N), O(N log N), O(N^2), etc). Be sure to justify your answer.
// sort(array, size, currpos): sorts the array positions currpos..size-1
// ---------------------------
// if currpos < size-1:
//    make a recursive call to sort positions currpos+1..size-1
//    move the value in array[currpos] into its correct sorted position using
//    tmp = size-1
//    while tmp > currpos AND array[tmp] < array[tmp-1]
//        swap the contents of array positions tmp and tmp+1
//        subtract one from tmp


Q2: Linked lists:
Below we provide the header file contents for a linked list class created by one of our team members, and the profile for a reverse method that we are required to implement.

Provide and implementation of the reverse method.
Do not implement any of the other linklist methods.
class linklist {
   private:
      struct node {
         int value;
         node* next;
      };
      node* front;
      node* back;

   public:
      linklist(); // initializes list to null
     ~linklist(); // deallocates all nodes
      // the bool functions return true if they succeed, false otherwise
      bool insert(int i); // inserts node with value i at front of list
      bool remove(); // removes and deletes element at back of list
      bool look(int p, int &i); // lookup value in position p
      void reverse(); // reverses order of nodes in the list
                      // (e.g. 1->3->7->2 would become 2->7->3->1)
};


Q3: Binary search trees:
Suppose we were building a binary search tree in which the keys are floating point values, with no duplicates, and smaller values go into the left subtree.

(i) Sketch what the tree would look like after we insert the following values (inserting in the order listed): 7.4, 2.8, 1.0, 9.9. 0.1, 4.3, 100.4, 17.6

(ii) Assuming we printed using an inorder traversal of the tree (left subtree, current node, right subtree), show the order the keys would be displayed in.

(iii) Assuming we deleted using a postorder traversal (left subtree, right subtree, currentnode), show the order in which the nodes would be deleted.


Q4: Constructors/operators:
The >> operator for cin can be overloaded much the same as the << operator we looked at for cout, using the istream type instead of the ostream.

For the class below, provide an overload of the >> operator that reads values for each of the data fields (any order is ok).
class datamix {
   protected:
      char c;
      int i;
      double d;
   public:
      datamix();
     ~datamix();
      void print();
};


Q5: Templated classes:
Suppose we had implemented a templated class named lump, as shown below: included:
template <class T>
class lump {
   private:
      T value1;
      T value2;
   public:
      lump() { }
     ~lump() { }
      void print() { cout << value1 << "," << value2 << endl; }
      void set(T v1, T v2) { value1 = v1; value2 = v2; }
      void swap() { T tmp = value1; value1 = value2; value2 = tmp; }
};
Assuming all appropriate libraries have been included, write a main routine that uses lump as follows:
  1. it declares variable LI as a lump of ints
  2. it declares variable LS as a lump of strings
  3. it sets LI's values as 3 and 4
  4. it sets LS's values as "hello" and "there"
  5. it swaps LS's values
  6. it prints LI's values


Q6: Inheritance:
Below we provide the header for a simple base class, assignment.

From this base class derive (publicly) a class named codeassign with the following specifications:
  1. All methods use the default (static) binding.
  2. Two new string fields are added: language and version.
  3. The print method is overridden by the derived class, which does a cout of the codeassign fields and then calls the inherited print method to print the inherited fields.
class assignment {
   protected:
      string Author;
      string Assign;
      float Value;
      float Mark;
   public:
      assignment();
     ~assignment();
      void print();
      void set(string auth="", string asgn="", float val=0, float mk=0);
      void get(string &auth, string &asgn, float &val float &mk);
};


Q7: Exceptions:
Suppose we have created our own class for exceptions, derived from std::exception:
class infoexc: public exception{
   protected:
     string info;
     double val;
   public:
     excinfo(string i="excinfo", double v=0) { info = i; val = v; }
     ~excinfo() { }
     void what() { cout << i << "(" << val << ")"; }
};
Write a code segment (this does not need to be a complete function or program) that uses try/throws/catches to accomplish the following:


Q8: Polymorphism/dynamic binding:
Below we provide the class definitions for a group of three classes plus a function and main routine using them. Currently these are set up to rely on static binding of methods.

(i) Rewrite the three classes to appropriately support dynamic binding of methods.

(ii) Describe the behavioural difference we would see when running the function under the dynamic binding approach, as opposed to the static binding approach.
#include <iostream>
#include <string>
using namespace std;

class list {
   protected:
      struct node {
         string data;
         node* next;
      };
      node* front;
      node* back;
   public:
      list() {
         front = NULL;
         back = NULL;
      }
     ~list() {
         while (front) {
            node *tmp = front;
            front = front->next;
            if (front == NULL) back = NULL;
            delete tmp;
         }
      }
      string remove() {
         string s = "";
         if (front) {
            s = front->data;
            front = front->next;
         }
         return s;
      }
      void insert(std::string s) {
         node* n = new node;
         n->data = s;
         n->next = front;
         if (!front) back = n;
         front = n;
      }
      void print() {
         node *tmp = front;
         while (tmp) {
            cout << tmp->data << endl;
            tmp = tmp->next;
         }
      }
};
class queue: public list {
   public:
      queue() { }
     ~queue() { }
      void enqueue(string s) {
         insert(s);
      }
      string dequeue() {
         return remove();
      }
      void print() {
         cout << "queue: ";
         list::print();
      }
};

class rotQ: public queue {
   public:
      rotQ() { }
     ~rotQ() { }
      void rotate() {
         if (front) {
            string s = remove();
            insert(s);
         }
      }
      void print() {
         cout << "rot: ";
         queue::print();
      }
};

void printstuff(list* L) {
    if (L) L->print();
}

int main()
{
   rotQ R;
   list L;
   queue Q;
   L.insert("L1");
   Q.enqueue("Q2");
   R.insert("R3");
   printstuff(&L);
   printstuff(&Q);
   printstuff(&R);
}


End of Exam

GOOD LUCK WITH THE REST OF YOUR EXAMS, AND HAVE A GREAT SUMMER!