Linked List Written Assignment

Due, Wednesday January 31, 8:00 am (electronically)
You are to write solutions to each of the problems given below. You should not spend time debugging them, running them, or testing them. These exercises are designed to have you think about what you're doing without using the computer. You should feel free to use the compiler to assist with syntactic errors, however, if you think this will be useful. You should type solutions to these problems using emacs (or some editor on your own machine) and submit the solution using the submit program:
    submit100 link solution.cc README
(you may need to use ~ola/bin/submit100 if your path doesn't have my bin in it).

Be sure to include your name, the time you spent, and a list of collaborators in the README file, and the solutions in the file solution.cc.

In all these problems assume that types Node and TNode exist as shown below.

    struct Node 
    {
        string info;
        Node * next;
        Node(const string & s, Node * follow = 0)    // constructor
        {
            info = s;
            next = follow;
        }
    };

    template <class Kind>
    struct TNode 
    {
        Kind info;
        TNode<Kind> * next;
        TNode(const Kind & k, TNode<Kind> * follow = 0)    // constructor
        {
            info = k;
            next = follow;
        }
    };

* Problem 1: Counting

Complete the function TotalChars whose header is given below. TotalChars returns the total number of occurrences of the character ch in all the strings in its parameter list. You should use the string member function length() to find the number of characters in a string and s[k] for the value of the k-th character (indexing starts at 0).

You should write this function both recursively and iteratively (non-recursively).

    int TotalChars(Node * list, char ch)
    // postcondition: returns # of occurrences of ch in all nodes of list


* Problem 2: Replicate

Write the function Replicate whose header is given below. Replicate adds new nodes to list so that nodes are replicated the number of times specified by parameter count. For example, if list is represented by
      ("apple","cat","xray")
Then the call Replicate(list,3) should change list as shown below.
    ("apple","apple","apple","cat","cat","cat","xray","xray","xray")

Note that list is not passed by reference.

    void Replicate(Node * list,int count)
    // precondition: list = a1, a2, ... an
    //                      1 < count
    // postcondition: list  = a1, a1, ... a1, ... an, an, ... an
    //                where each element appears count times


* Problem 3: Reverse

Complete the function Reverse whose header is given below. Reverse reverses the nodes of its parameter list. You should do this by manipulating pointers, not by swapping info fields. In writing Reverse you should maintain as an invariant the picture shown below. This invariant would be initialized by the statement: rev = NULL, where rev is a local variable, since initially no nodes have been reversed and all nodes need to be reversed.
    void Reverse(Node * & list)
    //precondition: list is represented by a1, a2, a3, ..., an
    //postcondition: list is represented by an, ..., a3, a2, a1
Here's the invariant. The picture should be "true" each time the loop test is evaluated.


* Problem 4: Remove

Write a function Remove that removes all nodes containing a specified item from a templated list. Assume that lists do not have header nodes. The call Remove(slist,"big") should remove all nodes containing the string "big" from a list whose first node is pointed to by slist defined as
   TNode<string> * slist;
The call Remove(ilist,33) should remove all nodes containing 33 from a list whose first nodes is pointed to by ilist defined as
   TNode<int> * ilist;

Write Remove both iteratively and recursively.

   template <class Kind>
   void Remove(TNode<Kind> * & list,const Kind & deadValue)
   // postcondition: all nodes containing deadValue have been removed
   //                from list

* Problem 5: Split++

Write a function ListSplit that will split a circular list containing an even number of nodes, say 2k, into two circular lists each of which contains k nodes. The function should have three parameters and should work so that the function call
          ListSplit(list,sub1,sub2);
will create new lists pointed to by parameters sub1, and sub2 from the list initially referenced by parameter list. After ListSplit has executed, the first parameter should be 0/NULL, i.e., new nodes are not created, but are redistributed evenly between the second and third parameters. It doesn't matter how you divide the nodes between the two lists.

The prototype for the function is:

   template <class Kind>
   void ListSplit(TNode<Kind> * & list, 
                  TNode<Kind> * & first, TNode<Kind> * & second);
(you should write a postcondition for the function)