简体   繁体   中英

tail-recursive function in self-defined list_t

I am working on a project based on a custom-defined data structure list_t in C++. Here is the predefined functions that would help me manipulate this list_t and the function I am asked to write which is called insert_list(list_t, list_t, int) is to be tail-recursive.

typedef Recursive_list list_t;

// EFFECTS: returns true if list is empty, false otherwise
bool list_isEmpty(const list_t& list);

// EFFECTS: returns an empty list.
list_t list_make();

// EFFECTS: given the list (list) make a new list consisting of
//          the new element followed by the elements of the
//          original list. 
list_t list_make(int elt, const list_t& list);

// REQUIRES: list is not empty
// EFFECTS: returns the first element of list
int list_first(const list_t& list);

// REQUIRES: list is not empty
// EFFECTS: returns the list containing all but the first element of list
list_t list_rest(const list_t& list);

// MODIFIES: cout
// EFFECTS: prints list to cout.
void list_print(const list_t& list);

The insert_list() function I am to write takes in two inputs both of type list_t and an additional integer n that is guaranteed not greater than the size of the first list_t and returns another list_t that contains the first n elements from the first list_t (in the order they appear in the original list_t), followed by the entire second list_t and then followed by the remaining elements (integers) of the first list_t. The constraint is that this function, and its helper functions if any, must be tail-recursive. See the prototype for insert_list() here:

/*
 * REQUIRES: n >= 0 and n <= the number of elements in first
 * EFFECTS: returns a list comprising the first n elements of
 *          "first", followed by all elements of "second",
 *           followed by any remaining elements of "first".
 *
 *     For example: insert (( 1 2 3 ), ( 4 5 6 ), 2)
 *            is  ( 1 2 4 5 6 3 ).
 */
list_t insert_list(list_t first, list_t second, int n);

I have spent days thinking and trying out ways to attack this but the furthest I got would have the first n numbers reversed. I did write a function that reverse a list_t but I wouldn't be able to reverse part of a list, only reversing an entire list is possible and it wouldn't fit into the tail-recursion structure I've come up with. I also wondered if I need to write two recursively functions that actually depend on each other but haven't come up with any useful solution down that road either.

You need to keep adding elements from the first list and decrementing n until it reaches zero. Then you need to keep adding elements from the second list until it is exhausted, and finally append the rest of the first list.

EDIT: the above description does not achieve tail-recursion. I have modified the implementation as a result. The approach is: while n is above zero, keep taking elements off the front of first and pre-pending them to second , while decrementing n . When n reaches zero, do the opposite: keep taking elements off the front of second and pre-pending them to first , until second is empty. This achieves a full tail-recursive implementation.

list_t insert_list(list_t first, list_t second, int n)
{
    if(n==0) {
        if(list_isEmpty(second))
            return first;
        else 
            return insert_list(list_make(list_first(second), first), list_rest(second), 0);
    }
    else {
        return insert_list(list_rest(first), list_make(list_first(first), second), n-1);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM