An abstract data type(ADT) is defined by describing
1. the logical structure of the information represented by an instance of the type |
Aspect I: Structures
List - either empty or consists of a finite collection of elements, arranged so that each element has at most one element following it and at most one element preceding it
Stack - a LIFO list
Queue - a FIFO list
Tree - each element may have more than one sucessor
Graph - each element may have more than one sucessor and
more than one predecessor
Rings - lists with first and last element linked
Bags - collections with no structure
Tables - each element of one collection is associated with
a single element of another collection
Aspect II: Operations
List - create, insert, delete, find, destroy
Stack - create, push, pop, destroy
ADTs and OOP
If all of the elements are of the same type, we have a homogeneous list, otherwise we have a heterogeneous list |
Some general categories of ADT operations are:
Specific operations for List:
Declaring the List Class
List of ???? - use parameterized class
template <class T> class TList { }
where T is now a place-holder for any type:
void Update(T x);
Tlist<T>& operator= (const Tlist<T>& lst);
and we would reference the TList class by TList<int> or
Tlist<Fraction>
example of a generic swap function:
template<class SWAP_TYPE> void Swap(SWAP_TYPE& a, SWAP_TYPE& b) { SWAP_TYPE temp = a; a = b; b = temp; }
Example of Array Implementation
//---------- ALISTS.H ---------- #ifndef ALISTS_H #define ALISTS_H #include <iostream.h> //-------------------------- TList // Declaration of an array implementation of list of values of parametrized type. // All insertion and deletion is done at the current position in the list. template <class T>class TList { friend ostream& operator<< (ostream& os, TList<T> l); public: TList(); // Construct an empty list. TList(const TList<T>& l); // copy constructor ~TList(); // destructor TList<T>& operator= (const TList<T>& l); // assignment overload void Insert(T x); // Insert x at current position void Remove(); // Delete the node at the current position void Head(); // Move current location to the head void Tail(); // Move current location to the tail TList<T>& operator++ (int); // Move current to next position (postfix) TList<T>& operator-- (int); // Move current to prior position (postfix) T Retrieve() const; // Return the element at the current position void Update(T x); // Store x in current location int Length(); // Return the size of the list private: T *value; // pointer to the array int size, // number of elements in the list (<= max) max, // size of the array current; // current index in the array (0 <=# current < size) void Grow(); // Grow the array to twice its size }; #endif
//---------- ALISTS.CPP ---------- #include <stdlib.h> // for exit #include "ALISTS.H" //----------------- Definition of TList member functions and friends template <class T> ostream& operator<< (ostream& os, TList<T> l) // Display an entire TList, from first position to last. { for (int i = 0; i < size; i++) os << value[i] << '\t'; return os; } template<class T> TList<T>::TList() // Default constructor. Builds an empty list, using an array of 10 elements. { size = 0; max = 10; current = 0; value = new T[max]; } template<class T> TList::TList(const TList & l) // copy constructor { size = l.size; max = l.max; current = l.current; value = new T[max]; for (int i = 0; i < size; i++) value[i] = l.value[i]; } template<class T> TList ::~TList() // Delete all nodes in the List. { delete []value; // We need the brackets because T might have its own destructor. size = 0; max = 0; current = 0; } template<class T> TList & TList ::operator= (const TList & l) // assignment overload { size = l.size; max = l.max; current = l.current; // Kill the old array and construct a new one, filling it with l's values delete []value; value = new T[max]; for (int i = 0; i < size; i++) value[i] = l.value[i]; return *this; } template<class T> void TList ::Insert(T x) // Insert x at the current position. { if (size == max) // No room in the array, so make it larger. Grow(); for (int i = size - 1; i >= current; i--) value[i + 1] = value[i]; value[current] = x; size++; } template<class T> void TList ::Remove() // Delete the node at the current position. // If the list is empty, display a warning, but continue working. { if (size > 0) { for (int i = current; i < size - 1; i++) value[i] = value[i + 1]; size--; } else cerr << "Attempt to Remove an element from an empty list" << endl; } template<class T> void TList ::Head() // Move current location to the head. { current = 0;} template<class T> void TList ::Tail() // Move current location to the tail. { if (size > 0) // We don't have to do anything if the list is empty. current = size - 1; } template<class T> TList & TList ::operator++ (int) // Move current location to next node (postfix operator). // Do nothing if current is at the tail of the list. { if (current < size - 1) current++; return *this; } template<class T> TList & TList ::operator-- (int) // Move current location to previous node (postfix operator). // Do nothing if current is at the head of the list { if (current > 0) current--; return *this; } template<class T> T TList ::Retrieve() const // Return the element at the current position. // Quit the program if the list is empty, since we can't return anything. { if (size > 0) return value[current]; else { cerr << "Cannot Return an element from an empty list"; exit(1); } } template<class T> void TList ::Update(T x) // Store x in current location. // Quit the program if the list is empty. { if (size > 0) value[current] = x; else { cerr << "Cannot Update an element in an empty list"; exit(1); } } template<class T> int TList ::Length() // Return the number of elements in the list. { return size;} template<class T> void TList ::Grow() // PRIVATE. Double the size of the array { max *= 2; T* newValue = new T[max]; for (int i = 0; i < size; i++) newValue[i] = value[i]; delete []value; value = newValue; }
template <class T> class Node { public: Node() {next = NULL;} data value; Node* next; }; //---------- LLISTS.CPP ---------- #include <stdlib.h> // for exit #include "LLISTS.H" //----------------- Definition of TList member functions and friends template<class T> ostream& operator<< (ostream& os, TList<T> l) // Display an entire TList, from first position to last. { Node<T>* p = l.first; while (p) { os << p->value << '\t'; p = p->next; } return os; } template<class T> TList<T>::TList() // Default constructor. Builds an empty list. { first = current = last = NULL; size = 0; } template<class T> TList<T>::TList(const TList<T>& l) // copy constructor { Node<T> *lptr = l.first, // tracks through the argument list *nptr; // tracks through this list if (lptr == NULL) { current = first = last = NULL; size = 0;} else { //---- Construct the first node in the list. nptr = new Node<T>; nptr->value = lptr->value; if (lptr == l.current) current = nptr; first = nptr; lptr = lptr->next; //---- Track through the remainder of the list, copying nodes. while (lptr) { nptr->next = new Node<T>; nptr = nptr->next; if (lptr == l.current) current = nptr; nptr->value = lptr->value; lptr = lptr->next; } nptr->next = NULL; last = nptr; size = l.size; } } template<class T> TList<T>::~TList() // Delete all nodes in the List. { Node<T>* nptr = first; current = first; while (current) { current = current->next; delete nptr; nptr = current; } first = current = last = NULL; size = 0; } template<class T> TList<T>& TList<T>::operator= (const TList<T>& l) // assignment overload { //--------- First, destroy the existing list. Node<T>* nptr = first; current = first; while (current) { current = current->next; delete nptr; nptr = current; } //--------- Now build the new list Node<T> *lptr = l.first; // tracks through the argument list if (lptr == NULL) { current = first = last = NULL; size = 0;} else { //---- Construct the first node in the list. nptr = new Node<T>; nptr->value = lptr->value; if (lptr == l.current) current = nptr; first = nptr; lptr = lptr->next; //---- Track through the remainder of the list, copying nodes. while (lptr) { nptr->next = new Node<T>; nptr = nptr->next; if (lptr == l.current) current = nptr; nptr->value = lptr->value; lptr = lptr->next; } nptr->next = NULL; last = nptr; size = l.size; } return *this; } template<class T> void TList<T>::Insert(T x) // Insert x at the current position. { Node<T>* nptr = new Node<T>; if (current == NULL) // List is empty. { nptr->value = x; nptr->next = NULL; current = first = last = nptr; } else // List is nonempty. { nptr->value = current->value; nptr->next = current->next; current->value = x; current->next = nptr; if (current == last) last = nptr; } size++; } template<class T> void TList<T>::Remove() // Delete the node at the current position. { //You fill it in!!! } template<class T> void TList<T>::Head() // Move current location to the head. { current = first;} template<class T> void TList<T>::Tail() // Move current location to the tail. { current = last;} template<class T> TList<T>& TList<T>::operator++ (int) // Move current location to next node (postfix operator). // Do nothing if current is at the tail of the list. { if (current != last) current = current->next; return *this; } template<class T> TList<T>& TList<T>::operator-- (int) // Move current location to previous node (postfix operator). // Do nothing if current is at the head of the list { if (current != first) { Node<T>* nptr = first; while (nptr->next != current) nptr = nptr->next; current = nptr; } return *this; } template<class T> T TList<T>::Retrieve() const // Return the element at the current position. { if (current) return current->value; else { cerr << "Attempted to Return an element from an empty list"; exit(1); } } template<class T> void TList<T>::Update(T x) // Store x in current location. { if (current) current->value = x; else { cerr << "Attempted to Update an element in an empty list"; exit(1); } } template<class T> int TList<T>::Length() // Return the number of nodes in the list. { return size;}
p = head; while (p) { process node; p = p -> next; }
Init | Done | ReadIn |
Display | Save | Empty |
Push | Pop | Top |
TStack* stackPtr; class TStack {public: TStack() // Used: To initialize the receiver stack. // Pre: None // Post: Receiver stack is initialized and Size = 0 // and Error = False and S = () ~TStack // Used: To destroy the receiver stack. // Pre: Receiver is initialized. // Post: Receiver stack is destroyed. void Push (T element) // Used: To add a new element onto the top of the stack. // Pre: S = (e[1] e[2] ... e[N]) and Size = N // Post: N < MaxElements and Size = N+1 and S = (e[1] e[2] ... e[N] Eptr) // or N = MaxElements and Error = True void Pop() // Used: To remove the top element from the stack. // Pre: S = (e[1] e[2] ... e[N]) and Size = N // Post: N = 0 and Error = True // or N > 0 and S = (e[1] e[2] ... e[N-1]) and Size = N-1 T Top() // Used: To access the element at the top of the stack // Pre: S = (e[1] e[2] ... e[N]) and Size = N // Post: N = 0 and Error = True and result = NIL // or N > 0 and result = e[N] }
Init | Done | ReadIn |
Display | Save | Empty |
Enqueue | Dequeue | Front |
Rear |
TQueue* queuePtr; class TQueue {public: TQueue // Used: To initialize the receiver queue. // Pre: None // Post: The receiver queue is intialized ~TQueue // Used: To destroy the receiver queue. // Pre: Receiver queue is initialized. // Post: The receiver queue is destroyed. void EnQueue(T element) // Used: To add a new object to the rear of the receiver queue // Pre: Q = (e[1] ... e[N]) and Size = N // Post: Size = MaxElements ^ Error = True or Size < MaxElements ^ Q = (e[1] ... e[N] Eptr) and Size = N + 1) void DeQueue() // Used: To remove an object from the front of the queue. // Pre: Q = (e[1] e[2] ... e[N]) and Size = N // Post: Size = 0 and Error = True or N > 0 ^ Q = (e[2] ... e[N]) and Size = N-1) void Empty T Front() // Used: To access the object at the front of the queue. // Pre: Q = (e[1] ... e[N]) and Size = N // Post: Size = 0 and result = Nil and Error = True or Size > 0 and result = e[1] T Rear(); // Used: To access the object at the rear of the queue. // Pre: Q = (e[1] ... e[N]) and Size = N // Post: Size = 0 and result = Nil and Error = True or Size > 0 and result = e[N] }