Table of Contents

Corning Community College

CSCS2320 Data Structures

~~TOC~~

Project: EOCE0

Errata

This section will document any updates applied to the project since original release:

Objective

In this project, we pursue our third rewrite of linked list code, this time implementing such functionality within an object-oriented fashion using C++ (in true OOP form, and not as a lazy C!)

This also serves as part of the End of Course Experience, which wraps up our Data Structures journey this semester.

Background

Hopefully by now, we have all grown rather familiar with the basic concepts surrounding nodes and linking them together, and all the fun/attention to detail/number of details/variations that can offer to problem solving.

As a means of furthering our conceptual understanding, while also gaining valuable programming experience, we will now undergo a rewrite in on object-oriented fashion, pursuing more than just the superficial objects/classes that are barely a third of the object-oriented experience.

And what are the other two-thirds? Why, inheritance and polymorphism, of course!

Project Overview

For this project, we're going to be implementing a linked list data structure utilizing nodes. Predominantly one should notice many similarities of conceptual flow– since we are just re-implementing something we've done twice before.

The big differences are syntactical and object-oriented conceptual. One thing we now have to content with is access control, which adds another layer of detail to things. But that also offers us some advantages.

Also, note the case, especially as “camel case” (ie the capitalization of first letters of words, frequently words that are smashed together to form a more descriptive variable name)… this tends to be part of the object-oriented programming culture, even if it isn't required by the language proper or any of its development tools.

In inc/Node.h

First up, let's start with something that, at its core, should be quite familiar:

1
#ifndef _NODE_H
#define _NODE_H
 
#include <cstdlib>
 
class Node {
    public:
             Node();
             Node(int);
        void setValue(int);
        int  getValue();
        virtual Node *copy() = 0;
        virtual void  setNext(Node *) { };
        virtual Node *getNext()       { return (NULL); };
        virtual void  setPrev(Node *) { };
        virtual Node *getPrev()       { return (NULL); };
        virtual ~Node();
 
    private:
        int  value;
};
 
#endif

The OOP Node class is now part of a hierarchy, and as such, is what is known as an abstract base class… what might seem weird, is this is really only a base reference point, we won't actually be making any Node objects (we can't, nor would we want to– Node as a class isn't actually useful), but deriving child classes from this class. And we will want to instantiate those derived classes.

But- to add a twist, through C++'s ability to upcast base class pointers and taking advantage of polymorphism, we will access the child class functionality THROUGH this class, keeping the naming simpler.

In inc/SinglyLinkedNode.h

The first node class we can make use of is that of the Singly Linked Node. Here, we see that the SinglyLinkedNode class inherits from Node, and in similar style, incorporates content from its parent class, and adds new functionality (specifically, the next pointer). So, SinglyLinkedNode is similar to the nodes used in the earlier parts of the semester.

Note that, due to access control, the ability to read/write the next pointer will be restricted outside of this class. As such, we implement two accessor functions: setNext() and getNext(), which will do the sanctioned and heavy lifting to allow outside parties access.

1
#ifndef _SINGLY_NODE
#define _SINGLY_NODE
 
#include <Node.h>
 
class SinglyLinkedNode : public Node {
        public:
                         SinglyLinkedNode();
                         SinglyLinkedNode(int);
                virtual Node *copy();
                void setNext(Node *);
                Node *getNext();
                        ~SinglyLinkedNode();
 
        private:
                Node *next;
};
 
#endif

In inc/DoublyLinkedNode.h

The DoublyLinkedNode class gets our node capabilities back to how we've been dealing with them of late– a node containing a value that has 2 pointers: next and prev

Due to inheritance, we get the value element stuff from the base Node class. We then get all the next element stuff from the SinglyLinkedNode class. As a result, DoublyLinkedNode is an extension of SinglyLinkedNode, which is itself an extension of the base Node class.

1
#ifndef _DOUBLY_NODE
#define _DOUBLY_NODE
 
#include <SinglyLinkedNode.h>
 
class DoublyLinkedNode : public SinglyLinkedNode {
    public:
        DoublyLinkedNode();
        DoublyLinkedNode(int);
        virtual Node *copy();
        void setPrev(Node *);
        Node *getPrev();
        ~DoublyLinkedNode();
 
    private:
        Node *prev;
};
#endif

In inc/List.h

Now that we have the classes needed to create and manipulate nodes, we move onto classes that oversee the coordinated manipulation of nodes– referenced from a new container letting us keep track of where to begin and to end, along with how many nodes are a part of this effort. We've come to call these 'lists', due to their sequential nature.

The List class is another abstract base class, meaning we cannot instantiate it, but it will provide some of the core building blocks so that it can be inherited into derived classes and used.

1
#ifndef _LIST_H
#define _LIST_H
 
#include <Node.h>
 
class List {
        public:
                List();
 
                virtual List *copy() = 0;
                int     getQuantity();
 
                virtual void  append(Node *, Node *) = 0;
                virtual void  insert(Node *, Node *) = 0;
                virtual Node *obtain(Node *) = 0;
 
                virtual void  display(int) = 0;
                virtual void  sort(int) = 0;
                virtual void  swap(Node *, Node *) = 0;
                virtual Node *find(int) = 0;
 
                virtual Node *getStart() = 0;
                virtual Node *getEnd() = 0;
 
                virtual ~List();
 
        protected:
                void  setQuantity(int);
 
                virtual void  setStart(Node *) = 0;
                virtual void  setEnd  (Node *) = 0;
 
                virtual Node *setListPosition(int) = 0;
                virtual int   getListPosition(Node *) = 0;
 
        private:
                int   quantity;
};
 
#endif

In inc/ListOfSinglyLinkedNodes.h

Here the ListOfSinglyLinkedNodes class is the analog to what we called a Singly-Linked List earlier in the semester. It has a start and end pointer, it maintains a quantity, and it implements operations to maintain the consistency of this particular grouping of nodes (the ability to insert(), append(), and obtain() nodes in a sane fashion, along with other helpful member functions).

1
#ifndef _SINGLY_LIST_H
#define _SINGLY_LIST_H
 
#include <List.h>
#include <SinglyLinkedNode.h>
 
class ListOfSinglyLinkedNodes : public List {
        public:
                ListOfSinglyLinkedNodes();
 
                virtual List *copy();
 
                virtual void  append(Node *, Node *);
                virtual void  insert(Node *, Node *);
                virtual Node *obtain(Node *);
 
                virtual void  display(int);
                virtual void  sort(int);
                virtual void  swap(Node *, Node *);
                virtual Node *find(int);
 
                Node *getStart();
                Node *getEnd();
 
                virtual ~ListOfSinglyLinkedNodes();
 
        protected:
                void  setStart(Node *);
                void  setEnd  (Node *);
 
                virtual Node *setListPosition(int);
                virtual int   getListPosition(Node *);
 
        private:
                Node *start;
                Node *end;
};
#endif

In inc/ListOfDoublyLinkedNodes.h

With the “List Of Doubly Linked Nodes”, we see an Object-Oriented C++ implementation of the data structure we affectionately came to know as the “Doubly Linked List”– ie a list of nodes connected to both their immediate next and previous neighbors.

1
#ifndef _DOUBLY_LIST_H
#define _DOUBLY_LIST_H
 
#include <DoublyLinkedNode.h>
#include <ListOfSinglyLinkedNodes.h>
 
class ListOfDoublyLinkedNodes : public ListOfSinglyLinkedNodes {
        public:
                ListOfDoublyLinkedNodes();
 
                virtual List *copy();
 
                virtual void  append(Node *, Node *);
                virtual void  insert(Node *, Node *);
                virtual Node *obtain(Node *);
 
                virtual void  display(int);
                virtual void  sort(int);
                virtual void  swap(Node *, Node *);
                virtual Node *find(int);
 
                virtual ~ListOfDoublyLinkedNodes();
 
        protected:
                virtual Node *setListPosition(int)    { return (NULL); };
                virtual int   getListPosition(Node *) { return (-1);   };
};
#endif

Project Requirements

For this project, it is your responsibility to:

For those interested in an extra credit opportunity (especially to make up for a missed project, such as sll2), you may fully complete both the functions and create unit tests to bring the ListOfSinglyLinkedNodes class fully on-line.

Submission Criteria

To be successful in this project, the following criteria must be met: