代码应打印出用户输入的列表1列表,告诉您列表有多长,让您搜索一个号码,然后删除一个号码。删除号码后,应该将其保存到列表2中,然后打印出数字。代码一直工作到列表2.由于某种原因,列表1要么不是列表2,要么就是不打印列表2.我很乐意帮助弄清楚为什么会发生这种情况。
的main.cpp
#include <iostream>
#include "circularLinkedList.h"
using namespace std;
void testCopyConstructor(circularLinkedList<int> oList);
int main()
{
circularLinkedList<int> list1, list2;
int num;
cout << "Enter number ending with -999" << endl;
cin >> num;
while (num != -999)
{
list1.insertNode(num);
cin >> num;
}
cout << endl;
cout << "List 1: ";
list1.print();
cout << endl;
cout << "Length List 1: " << list1.length() << endl;
cout << "Enter the number to be searched: ";
cin >> num;
cout << endl;
if (list1.search(num))
cout << num << " found in the list" << endl;
else
cout << num << " not in the list" << endl;
cout << "Enter the number to be deleted: ";
cin >> num;
cout << endl;
list1.deleteNode(num);
cout << "After deleting the node, "
<< "List 1: ";
list1.print();
cout << endl;
cout << "Length List 1: " << list1.length() << endl;
list2 = list1;
cout << "List 2: ";
list2.print();
cout << endl;
cout << "Length List 2: " << list2.length() << endl;
testCopyConstructor(list1);
cout << "List 1: ";
list1.print();
cout << endl;
return 0;
}
void testCopyConstructor(circularLinkedList<int> oList)
{
}
circularLinkedList.h
#ifndef H_circularLinkedList
#define H_circularLinkedList
#include <iostream>
#include <cassert>
using namespace std;
template <class Type>
struct nodeType
{
Type info;
nodeType<Type> *link;
};
template <class Type>
class circularLinkedList
{
public:
const circularLinkedList<Type>& operator=
(const circularLinkedList<Type>&);
//Overloads the assignment operator.
void initializeList();
//Initializes the list to an empty state.
//Postcondition: first = nullptr, last = nullptr,
// count = 0
bool isEmptyList();
//Function to determine whether the list is empty.
//Postcondition: Returns true if the list is empty;
// otherwise, returns false.
void print() const;
int length();
//Function to return the number of nodes in the
//list.
//Postcondition: The value of count is returned.
void destroyList();
//Function to delete all the nodes from the list.
//Postcondition: first = nullptr, last = nullptr,
// count = 0
Type front();
//Function to return the first element of the list.
//Precondition: The list must exist and must not be
//empty.
//Postcondition: If the list is empty, then the
// program terminates; otherwise,
// the first element of the list is
// returned.
Type back();
//Function to return the last element of the
//list.
//Precondition: The list must exist and must not
//be empty.
//Postcondition: If the list is empty, then the
// program terminates; otherwise,
// the last element of the list is
// returned.
bool search(const Type& searchItem);
//Function to determine whether searchItem is in
//the list.
//Postcondition: Returns true if searchItem is found
// in the list; otherwise, it returns
// false.
void insertNode(const Type& newitem);
void deleteNode(const Type& deleteItem);
//Function to delete deleteItem from the list.
//Postcondition: If found, the node containing
// deleteItem is deleted from the
// list, first points to the first
// node, and last points to the last
// node of the updated list.
circularLinkedList();
//Default constructor
//Initializes the list to an empty state.
//Postcondition: first = nullptr, last = nullptr,
// count = 0
circularLinkedList(const circularLinkedList<Type>& otherList);
//Copy constructor
~circularLinkedList();
//Destructor
//Deletes all the nodes from the list.
//Postcondition: The list object is destroyed.
protected:
int count; //variable to store the number of
//elements in the list
nodeType<Type> *first; //pointer to the first node of
//the list
nodeType<Type> *last; //pointer to the last node of
//the list
private:
void copyList(const circularLinkedList<Type>& otherList);
//Function to make a copy of otherList.
//Postcondition: A copy of otherList is created
// and assigned to this list.
};
template <class Type>
bool circularLinkedList<Type>::isEmptyList()
{
return (first == NULL);
// function to determine if list is empty
}
template <class Type>
circularLinkedList<Type>::circularLinkedList() // default constructor
{
first = nullptr;
count = 0;
}
template <class Type>
void circularLinkedList<Type>::destroyList()
{
nodeType<Type> *temp;
nodeType<Type> *current = NULL;
if (first != NULL)
{
current = first->link;
first->link = NULL;
}
while (current != NULL)
{
temp = current;
current = current->link;
delete temp;
}
first = NULL; //initialize last to NULL; first has already
//been set to NULL by the while loop
count = 0;
// function to destroy the list
}
template <class Type>
void circularLinkedList<Type>::initializeList()
{
destroyList(); //if the list has any nodes, delete them
}
template <class Type>
int circularLinkedList<Type>::length()
{
return count;
// function to find the length of the list
} // end length
template <class Type>
Type circularLinkedList<Type>::front()
{
assert(first != nullptr);
return first->link->info; //return the info of the first node
}//end front
template <class Type>
Type circularLinkedList<Type>::back()
{
assert(first != nullptr);
return first->info; //return the info of the first node
}//end back
template <class Type>
bool circularLinkedList<Type>::search(const Type& searchItem)
{
nodeType<Type> *current; //pointer to traverse the list
bool found = false;
if (first != NULL)
{
current = first->link;
while (current != first && !found)
{
if (current->info >= searchItem)
found = true;
else
current = current->link;
found = (current->info == searchItem);
}
}
return found;
}
// function to search the list for a given item
//end search
template <class Type>
void circularLinkedList<Type>::insertNode(const Type& newitem)
{
nodeType<Type> *current; //pointer to traverse the list
nodeType<Type> *trailCurrent; //pointer just before current
nodeType<Type> *newNode; //pointer to create a node
bool found;
newNode = new nodeType<Type>; //create the node
newNode->info = newitem; //store newitem in the node
newNode->link = NULL; //set the link field of the node
//to NULL
if (first == NULL) //Case 1 e.g., 3
{
first = newNode;
first->link = newNode;
count++;
}
else
{
if (newitem >= first->info)//e.g., 25 > 3
{
newNode->link = first->link;
first->link = newNode;
first = newNode;
}
else
{
trailCurrent = first; //e.g., 1 < 3
current = first->link;
found = false;
while (current != first && !found)
if (current->info >= newitem)
found = true;
else
{
trailCurrent = current;
current = current->link;
}
trailCurrent->link = newNode;
newNode->link = current;
}
count++;
}
// function to insert an item into the list
}//end insertNode
template <class Type>
void circularLinkedList<Type>::deleteNode(const Type& deleteItem)
{
nodeType<Type> *current; //pointer to traverse the list
nodeType<Type> *trailCurrent; //pointer just before current
bool found;
if (first == NULL) //Case 1; list is empty.
cout << "Can not delete from an empty list." << endl;
else
{
found = false;
trailCurrent = first;
current = first->link;
while (current != first && !found)
if (current->info >= deleteItem)
found = true;
else
{
trailCurrent = current;
current = current->link;
}
if (current == first)
{
if (first->info == deleteItem)
{
if (first == first->link)
first = NULL;
else
{
trailCurrent->link = current->link;
first = trailCurrent;
}
delete current;
count--;
}
else
cout << "The item to be deleted is not in the list." << endl;
}
else
if (current->info == deleteItem)
{
trailCurrent->link = current->link;
count--;
delete current;
}
else
cout << "Item to be deleted is not in the list." << endl;
}
// function to delete an item from the list
} //end deleteNode
//Overloading the stream insertion operator
template <class Type>
void circularLinkedList<Type>::print() const
{
nodeType<Type> *current; //pointer to traverse the list
current = first->link;
while (current != first) //while more data to print
{
cout << current->info << " ";
current = current->link;
}
cout << first->info << " ";
// function to print the list
}
template <class Type>
circularLinkedList<Type>::~circularLinkedList() // destructor
{
destroyList();
}//end destructor
template <class Type>
void circularLinkedList<Type>::copyList
(const circularLinkedList<Type>& otherList)
{
first = NULL;
copyList(otherList);
// function to copy the list
}//end copyList
//copy constructor
template<class Type>
circularLinkedList<Type>::circularLinkedList
(const circularLinkedList<Type>& otherList)
{
first = nullptr;
copyList(otherList);
}//end copy constructor
//overload the assignment operator
template <class Type>
const circularLinkedList<Type>& circularLinkedList<Type>::operator=
(const circularLinkedList<Type>& otherList)
{
if (this != &otherList) //avoid self-copy
{
copyList(otherList);
}//end else
return *this;
}
#endif
答案 0 :(得分:0)
Kristina,通过copyList
递归调用copyList(otherList);
,你只需要永远循环。
退后一步。在创建list1
的实例时,您已在list2
中默认构建main()
和circularLinkedList<int>
。因此,当您拨打电话list2 = list1;
时,您正在调用复制分配成员函数。在您当前的代码中,您的副本分配只需调用copyList
(这本身就很好)但是,您的copyList
有点薄,并且没有按照您的意图行事,例如仅包含:
template <class Type>
void circularLinkedList<Type>::copyList
(const circularLinkedList<Type>& otherList)
{
first = NULL;
copyList(otherList); /* what happens when you get here? */
// function to copy the list
}//end copyList
看到问题?你调用circularLinkedList<Type>::operator=
,调用circularLinkedList<Type>::copyList
,然后你再次反复调用同一个函数。
(这是您在调试器中注意的地方 - 在's'
中点击copyList
(步骤)之后,只看到first = NULL;
并在copyList
找到您的回复再次执行first = NULL;
,有些事情是错误的......)
但是,总体而言,您在程序结构方面正确思考并且复制分配调用copyList
,您只需要实际复制列表......
那该怎么办?您需要将otherList
引用中的所有节点复制到新列表。您可以轻松遍历otherList
,就像在print()
copyList
正上方一样,除了输出每个值之外,您需要insertNode
。
(在print()
中,您以first->link
开头而不是first
进行迭代的事实对于循环列表来说有点特殊,但是...这在这里比命名问题更重要其他任何事情,遍历工作正常)
在otherList
中遍历insertNode
并呼叫copyList
将与print()
中的遍历完全相同。它可以是简单的事情:
template <class Type>
void circularLinkedList<Type>::copyList
(const circularLinkedList<Type>& otherList)
{
nodeType<Type> *iter = otherList.first->link;
while (iter != otherList.first) {
this->insertNode (iter->info);
iter = iter->link;
}
this->insertNode (iter->info);
} //end copyList
(如果这对你更有意义,你可以使用current
而不是iter
,但我发现iter
更能描述我对参考做的事情,但那是只是个人偏好。)
现在,您的副本分配和复制构造函数应该可以正常调用。 testCopyConstructor
中完全不需要main()
。要测试副本分配和复制构造函数,您只需在main中添加另一个列表实例,该实例将调用复制构造函数而不是复制赋值,例如
list2 = list1; /* copy assignment called */
cout << "List 2: ";
list2.print();
cout << endl;
cout << "Length List 2: " << list2.length() << endl;
cout << "List 1: ";
list1.print();
cout << endl;
circularLinkedList<int> list3 (list2); /* copy constructor called */
cout << "\nList 3: ";
list3.print();
cout << "\n";
示例使用/输出
完全放入后,您应该能够按预期执行代码,例如:
$ ./bin/llcirmain
Enter number ending with -999
1 2 3 4 5 -999
List 1: 1 2 3 4 5
Length List 1: 5
Enter the number to be searched: 4
4 found in the list
Enter the number to be deleted: 3
After deleting the node, List 1: 1 2 4 5
Length List 1: 4
List 2: 1 2 4 5
Length List 2: 4
List 1: 1 2 4 5
List 3: 1 2 4 5
仔细看看,如果您有其他问题,请告诉我。 (并考虑从头文件中删除using namespace std;
,您不希望在可能使用标题的源文件中包含完整的标准命名空间。)