美文网首页
Data Structure: 2.Imperative-Sty

Data Structure: 2.Imperative-Sty

作者: 鱼游硅谷 | 来源:发表于2015-01-05 10:13 被阅读26次

    Problem Description:

    In the previous exercise we implemented some basic operations on functional-style linked lists; their distinguishing feature is that the pairs that make up the lists are immutable. In today’s exercise we will implement imperative-style linked lists in which the pairs that make up the lists are mutable.

    Your task is to write the same library of functions — nil, isNil, pair, head, tail, nth, length, append, and reverse — for imperative-style mutable linked lists as you wrote in the previous exercise for functional-style immutable linked lists.

    Analysis:

    We will use the well-known imperative language C instead of our usual language Scheme, because writing Scheme like that would make me cry. The basic data type that implements lists is the List, which is a struct; we will hard-wire the data type as int, but you could change that to a pointer to void if you want to be more general:

    typedef struct list {
    void *data;
    struct list *next;
    } List;
    

    Instead of providing nil and isNil, we will simply use the built-in NULL for nil and write xs == NULL or xs != NULL to determine if a List is nil. Likewise, getting the components of a pair is so simple we don’t bother to provide functions for them: the head of a list is xs->data and the tail of a list is xs->next.

    The insert function adds a new pair to the front of a list by allocating space for the new pair, assigning a value and a pointer to its two fields, and returning the new pair:

    List *insert(void *data, List *next) {
    List *new;
    
    new = malloc(sizeof(List));
    new->data = data;
    new->next = next;
    return new;
    }
    

    Getting the nth item in a list, or counting the length of a list, involves chasing pointers down the list in a while loop. Since C doesn’t have a standard error return, we use our own error function, which writes a message to stderr then exits the program with a return value of 2:

    int nth(List *xs, int n) {
    while (n > 0) {
    if (xs == NULL) {
    error(“nth out of bounds”);
    }
    n–;
    xs = xs->next;
    }
    return xs->data;
    }
    
    int length(List *xs) {
    int len = 0;
    while (xs != NULL)
    {
    len += 1;
    xs = xs->next;
    }
    return len;
    }
    

    Append walks down its first argument, then modifies the NULL pointer at the end of the list to point to its second argument:

    List *append(List *xs, List *ys) {
    List *new = xs;
    
    while (xs->next != NULL) {
    xs = xs->next;
    }
    
    xs->next = ys;
    return new;
    }
    

    Our last function is reverse, which is again destructive, modifying the current list in place by swapping pointers:

    List *reverse(List *list) {
    List *new = NULL;
    List *next;
    
    while (list != NULL)
    {
    next = list->next;
    list->next = new;
    new = list;
    list = next;
    }
    
    return new;
    }
    

    We haven’t bothered to collect the garbage we created; shame on me. I admit some trouble programming with C; it’s so ugly compared to Scheme.

    Code:

    You can see the program in action at http://programmingpraxis.codepad.org/JQIFfqOX.

    -from ProgrammingProxis

    相关文章

      网友评论

          本文标题:Data Structure: 2.Imperative-Sty

          本文链接:https://www.haomeiwen.com/subject/xaktxttx.html