我正试图扭转双重链表。根据堆栈溢出和Web上的其他问题,这是反转双向链表的正确方法;交换每个节点的next
和back
指针。由于某些原因,它不适合我,我无法调试它,因为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()崩溃。
答案 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;
}
}
现在,这有效。可以更好吗?可能,但重点是很容易理解发生了什么。
如果你在纸上绘制了需要做的事情,上面的内容可能与您在纸上绘制的内容最接近,即得到两个节点,看看项目是否介于两个节点之间,如果不是,请获取下一对节点等...