所以,我正在尝试使用虚拟节点创建一个LinkedList,但是,当运行每个函数的功能时,我遇到重载括号运算符的错误,假设返回给定的项目index:list [n]虽然我不确定代码可能有什么问题。
我花了几个小时看看为什么我在尝试运行每个功能时遇到错误。对不起,问题是如此模糊,但我觉得好像我遗失了一些东西,或者某些东西编码不好,我似乎无法察觉。
这是代码。
#ifndef _LINKED_LIST_GUARD
#define _LINKED_LIST_GUARD 1
#include <iostream>
#include <string>
#include "ListInterface.h"
template <typename T>
class LinkedList : public ListInterface<T>
{
private:
// Created in order to keep track of list size
int count = 0;
public:
// Default contructor
LinkedList()
{
_head = new Node;
_tail = new Node;
_head->_next = _tail;
}
private:
//
// Private node class to facilitate linked list
//
class Node
{
public:
T _data;
Node* _next;
// Constructor: default
Node(T d = T{}, Node* n = nullptr) : _data(d), _next(n) {}
~Node() { _next = nullptr; }
};
//
// Prevent copying and assigning
//
LinkedList(const LinkedList& rhs) {}
const LinkedList& operator=(const LinkedList& rhs) {}
public:
//
// LinkedList instance variables; we use dummy head and tail nodes in this implementation
unsigned _size;
Node* _head;
Node* _tail;
// Returns the value that the head points to, sinze _head is a dummy node.
T& first() const
{
return _head->_next->_data;
}
// Adds an item to the LEFT side of the linked list
void push(const T& x)
{
// Creates a new node with the user input data.
Node* current = new Node;
current->_data = x;
//Sets the node next to this node to be equal to what the head was previously pointing to.
current->_next = _head->_next;
//Finally, sets the user created node to be the first node within the list, then adds to the count.
_head->_next = current;
count++;
}
T& operator[](unsigned n)
{
//Starts at position one, since this would never return zero.
int position = 1;
//If the user input value is greater than the amount of items in the list
if (n > count)
{
//Throws a string exception.
throw std::string("Invalid Positon");
}
//Loops through the LinkedList
for (Node* current = _head->_next; current != _tail; current = current->_next)
{
//If the node at the current position is equal to the user input value
if (position == n)
{
//returns the current positions data, since it would be the data at user input position
return current->_data;
}
// If not, adds to position, and checks again.
position++;
}
return _head->_data;
}
//uses the pop function over and over until the list is empty, leaving only the _head and _tail dummy nodes.
void clear()
{
do
{
pop();
} while (count != 0);
}
bool contains(const T& target) const
{
//Loops through the LinkedList.
for (Node* current = _head->_next; current != _tail; current = current->_next)
{
//While looping, if the current node's data is equal to the user input target data, returns true.
if (current->_data == target)
return true;
}
// If it never finds anything, returns false.
return false;
}
bool pop()
{
//The head would only point to the tail if the list were empty.
if (_head->_next == _tail)
{
std::cout << "Unable to pop, list is empty ";
return false;
}
if (_head->_next != _tail)
{
//Creates a new node that has its values equal to the first node within the list.
Node* deleteNode = _head->_next;
//Sets the front of the node to be equal to the first node after the heads next node.
_head->_next = _head->_next->_next;
//Finally, deletes the node that deleteNode points to, and reduces the count
delete deleteNode;
count--;
return true;
}
//If the pop is unsucessful, returns false.
return false;
}
T& last() const
{
// There can't be a last value if the list is empty, so throws an exception
if (_head->_next == _tail)
{
//throw std::string("List is empty.");
std::cout << "List is empty";
}
if (_head->_next != _tail)
{
for (Node* current = _head->_next; current != _tail; current = current->_next)
{
//Loops through the list until the node that points to tail is located, then returns it.
if (current->_next == _tail)
return current->_data;
}
}
return _tail->_data;
}
int search(const T& target = T{}) const
{
//Once again, starts a position 1, since 0 is not a valid position
int position = 1;
//Loops through list
for (Node* current = _head->_next; current != _tail; current = current->_next)
{
//While looping, if the current node's data is equal to the user input target, returns the position
if (current->_data == target)
{
return position;
}
//Otherwise increases the position, and loops again.
position++;
}
// If it is unable to find the target in the list, returns -1.
return -1;
}
bool isEmpty() const
{
// If the _head points to the tail, that means there are no nodes in between, meaning it is empty.
if (_head->_next == _tail)
{
return true;
}
//Otherwise, return false.
return false;
}
unsigned size() const
{
//Returns the count, which is altered by remove, pop, and push.
return count;
}
bool remove(const T& target)
{
//Creates a node, whose data is initially null.
Node* deleteNode = nullptr;
//Creates another node to follow behind it.
Node* trailer = _head;
//Finally, creates a node that is to represent the current node that is being pointed at.
Node* current = _head->_next;
//Loops
while (current != _tail && current->_data != target)
{
trailer = current;
current = current->_next;
}
//If the data is current is equal to the target
if (current->_data == target)
{
// Sets the node to be deleted to current
deleteNode = current;
//then, sets current to the node right after.
current = current->_next;
//Finally, sets the trailer to the current node, since it's no longer needed
trailer->_next = current;
//Then, simply delets the node, and subtracts from the count.
delete deleteNode;
count--;
return true;
}
else
// If it is unable to find the targeted value, returns false.
std::cout << "unable to remove, item not in list" << std::endl;
return false;
}
//
// Internal consistency check
//
public:
virtual bool check() const
{
bool sizeConsistent = isSizeConsistent();
bool headTailConsistent = isEndConsistent();
if (!sizeConsistent) std::cerr << "Size inconsistent" << std::endl;
if (!headTailConsistent) std::cerr << "Head / Tail inconsistent" << std::endl;
return sizeConsistent && headTailConsistent;
}
//
// Stated size is accurate to the entire list
//
bool isSizeConsistent() const
{
int count = 0;
for (Node* current = _head->_next; current != _tail; current = current->_next)
{
count++;
}
return size() == count;
}
//
// Checks that the head and tail are defaulted properly and the
// respective next pointers are appropriate.
//
bool isEndConsistent() const
{
if (_head->_data != T{}) return false;
if (_tail->_data != T{}) return false;
if (_head->_next == nullptr) return false;
if (_tail->_next != nullptr) return false;
if (isEmpty() && _head->_next != _tail) return false;
if (!isEmpty() && _head->_next == _tail) return false;
return true;
}
};
#endif
有关修复的总体建议吗?