使用成员函数反转双向链接列表

时间:2014-11-21 15:53:36

标签: c++ data-structures doubly-linked-list

我正试图扭转双重链表。根据堆栈溢出和Web上的其他问题,这是反转双向链表的正确方法;交换每个节点的nextback指针。由于某些原因,它不适合我,我无法调试它,因为XCode 6的整个调试菜单显示为灰色。反向函数位于dll.cpp的底部。继承我的代码:

dll.h:

#ifndef dll_h
#define dll_h
#include <iostream>
using namespace std;
template <class ItemType>
struct NodeType
{
    ItemType info;
    NodeType* next;
    NodeType* back;
};


template <class ItemType>
class DoublyLinkedList
{
public:
    DoublyLinkedList();     // Class constructor.
    ~DoublyLinkedList();    // Class destructor.

    ////////// implement these functions //////////
    DoublyLinkedList(DoublyLinkedList<ItemType>& );
    void InsertItem(ItemType item);
    void DeleteItem(ItemType item);
    void reverseDoublyLinkedList();


    void FindItem(NodeType<ItemType>* listData, ItemType item, NodeType<ItemType>*& location, bool& found);
    int LengthIs() const;
    void MakeEmpty();
    void RetrieveItem(ItemType& item, bool& found);
    void ResetList();
    void GetNextItem(ItemType& item);

private:
    NodeType<ItemType>* listData;
    int length;
    NodeType<ItemType>* currentPos;
};
#endif

dll.cpp:

#include "DLL.h"
template<class ItemType>
DoublyLinkedList<ItemType>::DoublyLinkedList()
{
    listData = NULL;
    length =0;
    currentPos = NULL;

}
template<class ItemType>
void DoublyLinkedList<ItemType>::FindItem(NodeType<ItemType>* listData, ItemType item,
                                          NodeType<ItemType>*& location, bool& found)
// Assumption: ItemType is a type for which the operators "<" and
//  "==" are defined-either an appropriate built-in type or a
//  class that overloads these operations.
// Pre:  List is not empty.
// Post: If there is an element someItem whose key matches item's
//       key, then found = true; otherwise, found = false.
//       If found, location contains the address of someItem;
//       otherwise, location contains the address of the logical
//       successor of item.
{
    bool moreToSearch = true;

    location = listData;
    found = false;
    while (moreToSearch && !found)
    {
        if (item < location->info)
            moreToSearch = false;
        else if (item == location->info)
            found = true;
        else
        {
            location = location->next;
            moreToSearch = (location != NULL);
        }
    }
}


template <class ItemType>
int DoublyLinkedList<ItemType>::LengthIs() const
{
    return length;
}

template <class ItemType>
void DoublyLinkedList<ItemType>::MakeEmpty()
// Post: List is empty; all items have been deallocated.
{
    NodeType<ItemType>* tempPtr;

    while (listData != NULL)
    {
        tempPtr = listData;
        listData = listData->next;
        delete tempPtr;
    }
    length = 0;
}

template <class ItemType>
void DoublyLinkedList<ItemType>::ResetList()
{
    currentPos = NULL;
}

template <class ItemType>
void DoublyLinkedList<ItemType>::GetNextItem(ItemType& item)
{
    if (currentPos == NULL)
        currentPos = listData;
    else
        currentPos = currentPos->next;
    item = currentPos->info;
}
template <class ItemType>
void DoublyLinkedList<ItemType>::RetrieveItem(ItemType& item,
                                              bool& found)
{
    bool moreToSearch;
    NodeType<ItemType>* location;

    location = listData;
    found = false;
    moreToSearch = (location != NULL);

    while (moreToSearch && !found)
    {
        if (location->info < item)
        {
            location = location->next;
            moreToSearch = (location != NULL);
        }
        else if (item == location->info)
        {
            found = true;
            item = location->info;
        }
        else
            moreToSearch = false;
    }
}

template <class ItemType>
DoublyLinkedList<ItemType>:: ~DoublyLinkedList()    // Class destructor.
{
    MakeEmpty();
}

template <class ItemType>
void DoublyLinkedList<ItemType>::InsertItem(ItemType item)
{
    NodeType<ItemType>* node = new NodeType<ItemType>;
    node->info = item;
    if(!length)
    {
        listData = node;
        node->next = NULL;
        node->back = NULL;
        length++;
        return;
    }
    NodeType<ItemType>* temp =listData;
    if(temp->next == NULL)
    {
        if(temp->info < item)
        {
            node->next = NULL;
            node->back = temp;
            temp->next = node;
        }
        else
        {
            node->next = temp;
            node->back = NULL;
            temp->back = node;
        }
        length++;
        return;
    }
    while(1)
    {
        if(temp->info > item)
        {
            node->next = temp;
            node->back = temp->back;
            if(temp->back != NULL)
            {
                node->back->next = node;
            }
            if(temp->back == NULL)
                listData = node;
            node->back = temp->back;
            length++;
            return;
        }
        else if(temp->next == NULL)
        {
            node->next = NULL;
            node->back = temp;
            temp->next = node;
            length++;
            return;
        }
        temp = temp->next;
    }
}


template <class ItemType>
void DoublyLinkedList<ItemType>::DeleteItem(ItemType item)
{
    NodeType<ItemType>* node = listData;
    if(node == NULL)
        return;
    while(node != NULL && node->info != item)
        node = node->next;
    if(node == NULL)
        return;
    if(node->back != NULL)
        node->back->next = node->next;
    if(node->next != NULL)
        node->next->back = node->back;
    delete node;
    length--;
}

template <class ItemType>
DoublyLinkedList<ItemType>::DoublyLinkedList(DoublyLinkedList<ItemType>& original)
{
    length = 0;
    currentPos = NULL;
    listData = NULL;
    NodeType<ItemType>* copy = original.listData;
    while(copy != NULL)
    {
        InsertItem(copy->info);
        copy = copy->next;
    }
}

template<class ItemType>
void DoublyLinkedList<ItemType>::reverseDoublyLinkedList()
{
    if(listData == NULL || listData->next == NULL)
        return;
    NodeType<ItemType>* node = listData;

    while(node!=NULL)
    {
        swap(node->next, node->back);

        listData = node;

        node = node->back;
    }
    currentPos = NULL;
}

main.cpp中:

#include <iostream>
#include "dll.h"
#include "dll.cpp"

int main()
{
    DoublyLinkedList<int> s;
    s.InsertItem(3);
    s.InsertItem(4);
    s.InsertItem(1);
    s.DeleteItem(2);
    s.DeleteItem(4);
    cout<<"Length of s: "<<s.LengthIs()<<endl;
    DoublyLinkedList<int> t = s;
    cout<<"Length of t: "<<t.LengthIs()<<endl;
    t.InsertItem(5);
    t.InsertItem(13);
    t.InsertItem(10);
    t.InsertItem(-3);
    int a;
    t.ResetList();
    for(int i=0;i<t.LengthIs();i++)
    {
        t.GetNextItem(a);
        cout<<"Item #"<<i<<": "<<a<<endl;
    }
    cout<<endl;
    t.reverseDoublyLinkedList();
    t.ResetList();
    for(int i=0;i<t.LengthIs();i++)
    {
        t.GetNextItem(a);
        cout<<"Item #"<<i<<": "<<a<<endl;
    }
    cout<<endl;
}

无关,但如果有人能告诉我为什么XCode 6.1不会让我在我的新Macbook Pro上调试也会有所帮助。

编辑: 输出:

Length of s: 2
Length of t: 2
Item #0: -3
Item #1: 1
Item #2: 3
Item #3: 5
Item #4: 10
Item #5: 13

Item #0: 13
Item #1: 5
Item #2: 3
Item #3: 1
Program ended with exit code: 9

最后,它在行item = currentPos->info;上的成员函数GetNextItem()崩溃。

1 个答案:

答案 0 :(得分:0)

问题与您的InsertItem有关。现在,它过于复杂了。

您正在尝试按递增顺序插入项目。因此,最简单的方法是选择一对节点,然后查看该项是否介于该对之间。这是一个更简单的实现:

template <class ItemType>
void DoublyLinkedList<ItemType>::InsertItem(ItemType item)
{
    NodeType<ItemType>* node = new NodeType<ItemType>;
    node->info = item;
    if (!length)
    {
        listData = node;
        node->next = NULL;
        node->back = NULL;
        length++;
        return;
    }

    NodeType<ItemType>* temp = listData;
    while (temp)
    {
        // get the next node
        NodeType<ItemType>* nextNode = temp->next;

        // make sure we have a pair of nodes
        if (nextNode)
        {
            // test for inbetween
            if (item >= temp->info && item <= nextNode->info)
            {
                // set the pointers and return
                // make sure we set the node in-between the temp and nextNode
                temp->next = node;
                nextNode->back = node;

               // now set node to point to temp (back), and nextNode (next)
               // for the in-between to link correctly
                node->next = nextNode;
                node->back = temp;

               // increase the length and get out
                ++length;
                return;
            }
        }
        else
        {
           // we're at the last node, so only place for this is at the back
           // set the pointers and return
            temp->next = node;
            node->back = temp;

            // last node, so make sure it points to NULL as next
            node->next = NULL;

            // increase length and get out
            ++length;
            return;
        }
        // go to next node and get next pair   
        temp = nextNode;
    }
}

现在,这有效。可以更好吗?可能,但重点是很容易理解发生了什么。

如果你在纸上绘制了需要做的事情,上面的内容可能与您在纸上绘制的内容最接近,即得到两个节点,看看项目是否介于两个节点之间,如果不是,请获取下一对节点等...