20-CS-122-001 Computer Science II Spring 2012
Queue Class With Find and MoveToFront

Virtual functions, classes, inheritance, lists, queues, stacks, applications

Prev      Next      Lectures     q.3.cc     queue.3.h     queue.3.cc

#include <iostream>
using namespace std;

void intDisplay (ostream & out, void *object) {
   out << *(int *)object << " "; 
}

bool intFind (void *find, void *object) {
   return *(int *)find == *(int *)object;
}

class Queue;

class Cell {
friend ostream & operator<<(ostream & out, Queue &lst);
friend class Queue;
   Cell *next; void *object;
   Cell (void *o, Cell *n) { next = n; object = o; }
};

class Queue {
friend ostream & operator<<(ostream & out, Queue &que);
   Cell *tail;
   void (*disp)(ostream &, void *);
   bool (*find)(void *, void *);

public:
   Queue() { tail = NULL; disp = intDisplay; find = intFind; }
   Queue(void (*d)(ostream &, void *), bool (*f)(void *, void *)) {
      tail = NULL; 
      disp = d; 
      find = f;
   }

   void enqueue(void *t) {
      if (t == NULL) return;
      if (tail == NULL) {
         tail = new Cell(t, NULL);
         tail->next = tail;
      } else {
         Cell *h = new Cell(t, tail->next);
         tail->next = h;
         tail = h;
      }
   }

   void *dequeue() {
      if (tail == NULL) return NULL;
      Cell *ptr = tail->next;
      void *t = ptr->object;
      if (ptr != tail) tail->next = ptr->next; else tail = NULL;
      delete ptr;
      return t;
   }

   int isEmpty() {  return tail == NULL;  }

   // Returns pointer to an object matching "what",
   // if it is found, or NULL otherwise
   void *findIt (void *what) {
      for (Cell *ptr=tail ; ptr != tail ; ptr=ptr->next) 
	 if (find(what, ptr->object)) return ptr->object;
      if (find(what, tail->object)) return tail->object;
      return NULL;
   }

   // Moves an object matching "what" to front of list
   void moveToFront (void *what) {
      for (Cell *ptr=tail->next ; ptr != tail ; ptr=ptr->next) {
	 if (find(what, ptr->next->object)) {
	    if (ptr->next == tail) tail = ptr;
	    else {
	       Cell *tmp = ptr->next;
	       ptr->next = ptr->next->next;
	       tmp->next = tail->next;
	       tail->next = tmp;
	    }
	 }
      }
   }
};

ostream & operator<<(ostream & out, Queue &que) {
   Cell *t;
   if (que.isEmpty()) { 
      out << "(empty)";
   } else {
      for (Cell *ptr=que.tail->next ; ptr != que.tail ; ptr=ptr->next)
	 que.disp(out, ptr->object);
      que.disp(out, que.tail->object);
   }   
   out << "\n";
   return out;
}

class Object {
friend ostream & operator<<(ostream & out, Object & obj);
   char *str;

public:
   Object (char *s) { 
      str = new char[strlen(s)+1];
      strcpy(str,s);
   }
   
   char *getString() { return str; }
};

void objectDisplay (ostream & out, void *object) {
   out << ((Object *)object)->getString() << " ";
}

bool objectFind (void *x, void *y) {
   return !strcmp((char *)x, ((Object *)y)->getString());
}

ostream & operator<<(ostream & out, Object & obj) {
   out << obj.getString() << " ";
   return out;
}

int main () {
   Queue qq(objectDisplay, objectFind);
   qq.enqueue(new Object("Cincinnati"));
   qq.enqueue(new Object("Chicago"));
   qq.enqueue(new Object("Cleveland"));
   qq.enqueue(new Object("Columbus"));
   cout << "Queue: " << qq;
   cout << "Find:  " << *(Object *)qq.findIt((void *)"Columbus") << "\n";
   cout << "Mv2Ft: Columbus\n";
   qq.moveToFront((void *)"Columbus");
   cout << "Queue: " << qq;
   cout << "Mv2Ft: Chicago\n";
   qq.moveToFront((void *)"Chicago");
   cout << "Queue: " << qq;
   cout << "Mv2Ft: Chicago\n";
   qq.moveToFront((void *)"Chicago");
   cout << "Queue: " << qq;
   cout << "Mv2Ft: Cleveland\n";
   qq.moveToFront((void *)"Cleveland");
   cout << "Queue: " << qq;
}