简体   繁体   中英

Reversing a generic doubly-linked list in C++

I'm trying to give my generic list class a reverse function. For some reason, my algorithm ain't workin' when I test it. I thought it made sense: swap the pointers to the first and last nodes of the list, then go through the list and for each node swap its pointers to the previous and next node.

Go easy on me, guys. I'm trying to get some practice with generic programming. Teach me the ways of a C++ purist.

Here's the swap function:

template <class T> void swap(T* a, T* b) { 
T* tempPtr = a;
a = b;
b = tempPtr;
}

Here's the reverse function:

template <class T> void List<T>::reverse() { 
    if (size > 1) { 
        swap(firstNodePtr, lastNodePtr);
        node* curNodePtr = firstNodePtr;
        while (curNodePtr != NULL) {
            swap(curNodePtr->prevNodePtr, curNodePtr->nextNodePtr);
            curNodePtr = curNodePtr->nextNodePtr;
        }
    }
}

Here's the class, its members and prototypes for functions:

template <class T> class List { 

public: 
    List();
    ~List();
    void push_back(T);
    void push_front(T); 
    T get_at(unsigned);
    unsigned get_size();
    void reverse();

private:
    struct node { 
        T val;
        node* prevNodePtr;
        node* nextNodePtr;
    };
    node* firstNodePtr;
    node* lastNodePtr;
    unsigned size;

};

Your swap<T> function does not work: it exchanges pointers, which are copied by value into local variables of your function, which has no effect in the caller.

Dropping your own swap and replacing it with std::swap will fix this problem.

Since you pass the two pointers by value, the changes to a and b don't propagate out of the swap() function, making it a no-op.

One way to fix it is by passing the pointers by reference:

template <class T> void swap(T*& a, T*& b) { 

Alternatively (and preferably) just use std::swap() instead of your own function.

If you exposed your node structure (or at least a bidirectional iterator type for your list), you could avoid the whole issue and just use std::reverse .

List<int> someList;
// fill with data
std::reverse(someList.begin(), someList.end()); // where begin returns a bidirectional iterator for the head, and end returns a bidirectional iterator for 1 element beyond the tail

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