In: Computer Science
For this program you will add and test 2 new member functions to the class in
//************************  intSLList.h  **************************
//           singly-linked list class to store integers
#ifndef INT_LINKED_LIST
#define INT_LINKED_LIST
class IntSLLNode {
public:
    IntSLLNode() {
        next = 0;
    }
    IntSLLNode(int el, IntSLLNode *ptr = 0) {
        info = el; next = ptr;
    }
    int info;
    IntSLLNode *next;
};
class IntSLList {
public:
    IntSLList() {
        head = tail = 0;
    }
    ~IntSLList();
    int isEmpty() {
        return head == 0;
    }
    void addToHead(int);
    void addToTail(int);
    int  deleteFromHead(); // delete the head and return its info;
    int  deleteFromTail(); // delete the tail and return its info;
    void deleteNode(int);
    bool isInList(int) const;
    void printAll() const;
private:
    IntSLLNode *head, *tail;
};
#endif
The two member functions are:
insertByPosn(int el, int pos)
Assuming that the positions of elements of a list begin numbering at 1 and continue to the end of the list, you will insert a new node with info value el at position pos. pos will become the position of the new node in the modified list. For example, if pos = 1, insert the new node at the head of the list. If pos = 2, for example, insert the new node BEFORE the node currently at position 2. If the list is empty prior to insertion, insert the new node in the list and adjust head and tail pointers. If pos is too large, don't do anything. If pos is 0 or negative, don't do anything.
removeByPosn(int pos)
Assume position of elements are defined as above. If pos is zero or negative, do nothing. If the list is empty prior to the request to delete a node, do nothing. If pos is too large, do nothing.
To aid in verifying results, you should use the following modified version of printAll. This requires: #include <string>
void IntSLList::printAll(string locn) const {
cout << "Contents of the list " << locn << endl;
for (IntSLLNode *tmp = head; tmp != 0; tmp = tmp->next)
cout << tmp->info << " ";
if (head != 0)
cout << "Head is: " << head->info << " Tail is: " << tail->info << endl << endl;
}
For extra credit, you can also create the following:
reverseList()
Traverse the existing list beginning at the head and create a new (reversed) list with head newhead and tail newtail. Put new nodes in the new list by putting the new nodes at the head of the new list each time. Do not call any other member functions during this process. If the list to be reversed is empty, make sure that you account for this case. After the new (reversed) list is created, delete the old list using its destructor.
The test program to be used is:
int main()
{
IntSLList singly_linked_list = IntSLList();
singly_linked_list.addToHead(9);
singly_linked_list.addToHead(7);
singly_linked_list.addToHead(6);
singly_linked_list.printAll("at creation:");
singly_linked_list.insertByPosn(8, 2);
singly_linked_list.printAll("after insertion of 8 at position 2:");
singly_linked_list.insertByPosn(10, 4);
singly_linked_list.printAll("after insertion of 10 at position 4:");
singly_linked_list.insertByPosn(12, 6);
singly_linked_list.printAll("after insertion of 12 at position 6:");
singly_linked_list.insertByPosn(14, 8);
singly_linked_list.printAll("after attempted insertion of 14 at position 8:");
singly_linked_list.insertByPosn(5, 1);
singly_linked_list.printAll("after insertion of 5 at position 1:");
singly_linked_list.insertByPosn(4, 0);
singly_linked_list.printAll("after attempted insertion of 4 at position 0:");
singly_linked_list.removeByPosn(2);
singly_linked_list.printAll("after deletion of 6 at position 2:");
singly_linked_list.removeByPosn(6);
singly_linked_list.printAll("after deletion of 12 at position 6:");
singly_linked_list.removeByPosn(10);
singly_linked_list.printAll("after attempted deletion at position 10:");
// insert test for optional list reversal here
return (0);
}
The correct output from running the test program is:
Contents of the list at creation:
6 7 9 Head is: 6 Tail is: 9
Contents of the list after insertion of 8 at position 2:
6 8 7 9 Head is: 6 Tail is: 9
Contents of the list after insertion of 10 at position 4:
6 8 7 10 9 Head is: 6 Tail is: 9
Contents of the list after insertion of 12 at position 6:
6 8 7 10 9 12 Head is: 6 Tail is: 12
Contents of the list after attempted insertion of 14 at position 8:
6 8 7 10 9 12 Head is: 6 Tail is: 12
Contents of the list after insertion of 5 at position 1:
5 6 8 7 10 9 12 Head is: 5 Tail is: 12
Contents of the list after attempted insertion of 4 at position 0:
5 6 8 7 10 9 12 Head is: 5 Tail is: 12
Contents of the list after deletion of 6 at position 2:
5 8 7 10 9 12 Head is: 5 Tail is: 12
Contents of the list after deletion of 12 at position 6:
5 8 7 10 9 Head is: 5 Tail is: 9
Contents of the list after attempted deletion at position 10:
5 8 7 10 9 Head is: 5 Tail is: 9
C++ code : updated code is in bold text
intSLList.h
//=====================================================================
// singly-linked list class to store integers
#ifndef INT_LINKED_LIST
#define INT_LINKED_LIST
#include<string>
#include<iostream>
using namespace std;
class IntSLLNode {
public:
   IntSLLNode() {
       next = 0;
   }
   IntSLLNode(int el, IntSLLNode *ptr = 0) {
       info = el; next = ptr;
   }
   int info;
   IntSLLNode *next;
};
class IntSLList {
public:
   IntSLList() {
       head = tail = 0;
   }
   ~IntSLList();
   int isEmpty() {
       return head == 0;
   }
   void addToHead(int);
   void addToTail(int);
   int deleteFromHead(); // delete the head and return
its info;
   int deleteFromTail(); // delete the tail and return
its info;
   void deleteNode(int);
   bool isInList(int) const;
   void printAll() const;
   // new added member function
   void insertByPosn(int el, int pos);
   void removeByPosn(int pos);
IntSLList reverseList();
   //for testing purpose
   void printAll(string locn) const;
private:
   IntSLLNode *head, *tail;
};
#endif
//=====================================================================
insLList.cpp
//=====================================================================
#include"intSLList.h"
void IntSLList::insertByPosn(int el, int pos)
{
   // do nothing when position is zero or negative - do
nothing
   // if (pos <= 0) return;
   // create new node and point tmp pointer to
created node
   IntSLLNode *tmp = new IntSLLNode(el, 0);
   if (pos == 1)
   {
       //if linklist is empty. add first
node to list
       //make head and tail both pointer
to point only node
       if (head == 0)
       {
           head =
tmp;
           tail =
tmp;
       }
       // if linklist is not empty add old
linklist after new node and
       // update head to point new
node
       else
       {
           tmp->next =
head;
           head =
tmp;
       }
       // we can simply call addToHead
function but i'm not sure is it allowed here
       // addToHead(el);
   }
   else if (pos>1)
   {
       IntSLLNode *find = head;
       int i;
       //move to node one before
position
       for (i = 1; i < pos-1;
i++)
       {
           if
(find->next != 0) find = find->next;
           else
break;
       }
       // pos is too large we have not
reached to given position - do nothing
       //if (i != (pos - 1))
return;
       if (i == (pos-1))
       {
           tmp->next =
find->next; // connect old "pos" node after new
node    tmp --> "pos"node
           find->next =
tmp;        // connect new node
to "pos-1" node      "pos-1" node -->
tmp --> "pos" node
           //pos-1 is last
position then update to new pos element;
           if (find ==
tail)
           {
          
    tail = tmp;
           }
       }
   }
}
void IntSLList::removeByPosn(int pos)
{
   // list is empty or position is zero or negative - do
nothing
   if (head == 0 || pos <= 0) return;
   // position is 1 then remove head
node
   if (pos == 1)
   {
       IntSLLNode *tmp = head;
       head = head->next;
       delete(tmp);
       if (head == 0) tail = 0; // if
updated list is empty than update tail
   }
   else
   {
       IntSLLNode *find = head;
       int i;
       //move to node one before
position
       for (i = 1; i < pos - 1;
i++)
       {
           if
(find->next!= 0) find = find->next;
           else
break;
       }
       // pos is too large we have not
reached to given position - do nothing
       //if (i != (pos - 1))
return;
       if (i == (pos -
1))
       {
           //pos-1 is last
position then nothing to update
           if (find ==
tail) return;
           else
           {
          
    //"pos" node is tail node then update tail
node
          
    if (find->next == tail) tail = find;
          
    //"pos-1" node --> "pos" node --> "pos+1"
node
          
    //"pos-1" node --> "pos+1" node
          
    IntSLLNode *tmp = find->next;
          
    find->next = find->next->next; //
connect old "pos-1" node to "pos+1"node
          
    delete(tmp);
           }
       }
   }
}
IntSLList IntSLList::reverseList()
{
   IntSLList *reversed = new IntSLList();
   // list is empty
   if (head == 0) return (*reversed);
   // single element list
   IntSLLNode *tmp;
   // create head node for reversed list
   IntSLLNode *reversed_head = new
IntSLLNode(head->info, 0);
   reversed->head = reversed_head;
   reversed->tail = reversed_head;
   // iterate from second element to last
element
   for (tmp = head->next; tmp != 0; tmp =
tmp->next)
   {
       // create a new node with next is
pointing to head of list
       IntSLLNode *reversed_new = new
IntSLLNode(tmp->info, reversed->head);
       // update head of list
       reversed->head =
reversed_new;
   }
   this->~IntSLList(); // deleting old list
   return *reversed;    // return object
of IntsLList
}
/******* following defination are just for compilation at my
end
you can update with you own defination ***/
void IntSLList::printAll(string locn) const {
   cout << "Contents of the list " << locn
<< endl;
   for (IntSLLNode *tmp = head; tmp != 0; tmp =
tmp->next)
       cout << tmp->info <<
" ";
   if (head != 0)
       cout << "Head is: " <<
head->info << " Tail is: " << tail->info <<
endl << endl;
}
void IntSLList::addToHead(int el)
{
   // create new node and point tmp pointer to created
node
   IntSLLNode *tmp = new IntSLLNode(el, 0);
   //if linklist is empty. add first node to list
   //make head and tail both pointer to point only
node
   if (head == 0)
   {
       head = tmp;
       tail = tmp;
   }
   // if linklist is not empty add old linklist after new
node and
   // update head to point new node
   else
   {
       tmp->next = head;
       head = tmp;
   }
}
void IntSLList::addToTail(int el)
{
   // create new node and point tmp pointer to created
node
   IntSLLNode *tmp = new IntSLLNode(el, 0);
   //if linklist is empty. add first node to list
   //make head and tail both pointer to point only
node
   if (head == 0)
   {
       head = tmp;
       tail = tmp;
   }
   // if linklist is not empty add new node end of old
linklist and
   // update tail to point new node
   else
   {
       tail->next = tmp;
       tail = tmp;
   }
}
int IntSLList::deleteFromHead() // delete the head and return
its info;
{
   // empty list
   if (head == 0) return -1; // not specified what we
need to return when it is empty
   int temp = head->info; // store info of head
pointer
   head = head->next;      //
move head pointer to next node
   if (head == 0) tail = 0;// if new list is empty then
change tail pointer also
   return temp;
}
int IntSLList::deleteFromTail() // delete the tail and return its
info;
{
   if (tail == 0) return -1;   // not specified
what we need to return when it is empty
   int temp = tail->info;   // store info of
tail pointer
   if (head == tail) // only one node
   {
       head = 0;
       tail = 0;
       return temp;
   }
   // start from head and find node whose next node is
tail
   IntSLLNode *tmp;
   for ( tmp= head; tmp->next == tail; tmp =
tmp->next);
   tmp->next = 0;    // remove current
tail node;
   tail = tmp;       //
update tail to new last node
   return temp;
}
void IntSLList::deleteNode(int el)
{
   //empty list
   if (head == 0) return;
   //single node list
   if (head->info == el)
   {
       head = 0;
       tail = 0;
       return;
   }
   // start from head and find node whose next node's
info is el
   // as we are looking at next node so tmp pointer will
only look for tail
   IntSLLNode *tmp;
   for (tmp = head; tmp != tail; tmp =
tmp->next)
   {
       if (tmp->next->info ==
el)
       {
           //remove middle
node by connecting directly to next to next node;
           tmp->next =
tmp->next->next;
           return;
       }
   }
//else not found
}
bool IntSLList::isInList(int el) const
{
   IntSLLNode *tmp;
   for (tmp = head; tmp != 0; tmp = tmp->next);
   {
       if (tmp->info == el) return
true;   // element found
   }
   return false; // element not found
}
void IntSLList::printAll() const
{
   for (IntSLLNode *tmp = head; tmp != 0; tmp =
tmp->next)
       cout << tmp->info <<
" ";
   if (head != 0)
       cout << "Head is: " <<
head->info << " Tail is: " << tail->info <<
endl << endl;
}
IntSLList::~IntSLList()
{
   IntSLLNode *tmp1,*tmp = head;
   while (tmp!=0)
   {
       tmp1 = tmp;
       tmp = tmp->next; // move to next
node;
       delete(tmp1);    //
delete previous node;
   }
   head = 0;
   tail = 0;
}
//=====================================================================
main.cpp
//=====================================================================
#include<iostream>
#include"intSLList.h"
using namespace std;
int main()
{
IntSLList singly_linked_list = IntSLList();
   singly_linked_list.addToHead(9);
   singly_linked_list.addToHead(7);
   singly_linked_list.addToHead(6);
   singly_linked_list.printAll("at creation:");
   singly_linked_list.insertByPosn(8, 2);
   singly_linked_list.printAll("after insertion of 8 at
position 2:");
   singly_linked_list.insertByPosn(10, 4);
   singly_linked_list.printAll("after insertion of 10 at
position 4:");
   singly_linked_list.insertByPosn(12, 6);
   singly_linked_list.printAll("after insertion of 12 at
position 6:");
   singly_linked_list.insertByPosn(14, 8);
   singly_linked_list.printAll("after attempted insertion
of 14 at position 8:");
   singly_linked_list.insertByPosn(5, 1);
   singly_linked_list.printAll("after insertion of 5 at
position 1:");
   singly_linked_list.insertByPosn(4, 0);
   singly_linked_list.printAll("after attempted insertion
of 4 at position 0:");
   singly_linked_list.removeByPosn(2);
   singly_linked_list.printAll("after deletion of 6 at
position 2:");
   singly_linked_list.removeByPosn(6);
   singly_linked_list.printAll("after deletion of 12 at
position 6:");
   singly_linked_list.removeByPosn(10);
   singly_linked_list.printAll("after attempted deletion
at position 10:");
   // added for reveresing linklist test
   IntSLList reversed =
singly_linked_list.reverseList();
   reversed.printAll("after reversing
singly_linked_list:");
return (0);
}
//=====================================================================
compile: g++ main.cpp intSLList.cpp
run: ./a.out
output:
