所以我有一个半工作的链表程序。我只是在某些方法上遇到了一些麻烦。。。。我记录的那些bekiw正在工作,除了从结尾删除,这表现得很奇怪。
我在Mavericks上使用NetBeans,C++作为我的编译器,C++11这是所有程序文件的zip
以下是我尝试制作的方法列表:
//working
int size() const;
/kind of
void addToStart(Node *);
//working
void addToEnd(Node *);
//working
void printList();
//working
bool removeFromStart();
//kind of working
bool removeFromEnd();
//Still working on these
void removeNodeFromList(int);
void removeNodeFromList(string);
目前,我必须运行removeFromEnd()两次才能使其工作。也就是说,我在程序开始时运行它一次,它什么都不做,但每次之后,它都会删除。
对于addToStart(),如果我只运行一次,它就可以工作。I.E:
- 我可以在程序开始时运行一次,然后打印出列表
- 我可以在使用addToEnd后运行它一次,但如果我第二次尝试,并且我试图打印出列表,它就会不断吐出我试图添加的值
addToEnd()工作得很好,如果我只是继续运行它,但如果I:,它会失败
首先使用addToEnd()添加项目,然后使用addToStart()一次,然后再次尝试使用addToEnd。当我打印出列表时,它只打印出两个对象,每个对象都是我试图插入的最后一个值的副本。
void LinkedList::addToEnd(Node* ne)
{
Node** q = &myHead;
while (*q)
{
q = &(*q)->next;
}
*q = new Node(ne->itemName, ne->itemNo);
}
void LinkedList::printList()
{
Node* p = myHead;
while (p != NULL)
{
cout << p->itemNo << " " << p->itemName;
cout << endl;
p = p->next;
}
cout << endl << endl;
}
bool LinkedList::removeFromStart()
{
if (myHead == NULL)
{
cout << "List is already empty";
}
else
{
myHead = myHead->next;
}
}
bool LinkedList::removeFromEnd()
{
if (myHead == NULL)
return false;
//Empty the list if there's only one element
if (myHead->next == NULL)
{
delete myHead;
myHead = NULL;
myTail = NULL;
return true;
}
// Find the last item in the list
Node *temp = myHead;
while (temp->next != myTail)
{
temp = temp->next;
}
delete myTail;
temp->next = NULL;
myTail = temp;
return true;
}
此外,仍在试图找出删除的
void LinkedList::removeNodeFromList(int i) {
//Save the values
Node* p = myHead;
Node* temp = myHead->next;
while (p) {
if (p->itemNo == i) {
p=temp;
} else {
p = p->next;
}
}
}
您有一个tail
指针,那么为什么要遍历列表以找到末尾呢?此外,为什么要通过指针传递节点?
void LinkedList::addToEnd(Node ne)
{
if (myHead == nullptr) // empty list
{
myHead = myTail = new Node(ne);
myTail->next = nullptr;
}
else
{
myTail->next = new Node(ne); // assuming Node has an accessible copy constructor
myTail = myTail->next;
}
}
removeFromStart
函数内存泄漏:
bool LinkedList::removeFromStart()
{
if (myHead == nullptr)
{
cout << "List is already empty";
return false;
}
Node* temp = myHead;
myHead = myHead->next;
if (myTail == temp) // if there is only 1 element in the list, head == tail
{
myTail = myhead;
}
delete temp;
return true;
}
据推测,removeFromEnd
应该移除尾部:
bool LinkedList::removeFromEnd()
{
if (myTail == nullptr)
return false;
// unless you have a doubly-linked list, loop to find 1 before the tail
Node* temp = nullptr;
for (temp = myHead; temp && temp->next != myTail; temp = temp->next);
if (myHead == temp) // when there is only 1 element in the list, head == tail
{
delete temp->next;
myHead = nullptr;
myTail = nullptr;
}
else
{
delete temp->next;
temp->next = nullptr;
myTail = temp;
}
return true;
}
是的,您正在使用new
(在addtoEnd
函数中),因此必须使用delete
(而不是free
!)。
附带说明:您可以使用std::unique_ptr
更好地编写remove代码(实际上,您可以通过在任何地方使用它来改进代码的整体性),这将使您的代码每行大约有4行长。我把它留给你来执行。
您有一个名为myTail
的成员,您似乎在使用"有时"
在addFromEnd中,您不会更新myTail。在其中一个remove函数中,即使您可能会更改myTail,也不会更新它但在RemoveFromTail中,您正试图使用它。
myTail没有理由包含有效值,当您尝试使用它时,可能会出现错误(因为节点可能已被删除)或意外结果,因为它只是指向列表中的某个位置。
您应该丢失它(因为您可以很容易地找出尾部。它是next==NULL的节点),或者在每次更改List的调用中小心维护它(只有尾部明显受到影响时)
由于您使用的是c++11,因此有以下几点建议:
const Node&
而不是Node*
就更清楚了。对我来说,Node*让人觉得你要使用用户提供的ptr。