Linked List Written Assignment, CPS 100

Due, Tuesday, February 4, 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. Again, do not run and debug. Instead, think.

You should type solutions to these problems using xemacs (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 directory 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. For problems that use doubly-linked lists assume the other pointer field is named previous.

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 each string in 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)
    // precondition: list has a header node
    // 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. Assume that Node has been modified so that it can be used for a doubly linked list.

    void Replicate(Node * list,int count)
    // precondition: list = a1, a2, ... an, 1 < count
    //                      doubly linked, NO header node, 
    // 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. Your code will run in O(n) time for an n-node list if you do this correctly.


* Problem 4: RemoveAllBut

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

The call RemoveAllBut(ilist,33) should remove all nodes except those containing 33 from a list whose first nodes is pointed to by ilist defined as TNode<int> * ilist; . The order of the nodes that aren't removed should be the same as before RemoveAllBut is called.

Write RemoveAllBut recursively.

template <class Kind> void RemoveAllBut(TNode<Kind> * & list,const Kind & value) // postcondition: all nodes except those containing value // 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. Note that you should make no assumptions about the values of first and second in the body of ListSplit.

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)